Следующий раздел кода является основным и отвечает за следующее:
• создание канала с помощью функции ChannelCreate;
• вызов подпрограммы setupPulseAndTimer (для настройки периодического таймера, срабатывающего раз в секунду и использующего импульс в качестве способа доставки события;
• и, наконец, бесконечный цикл ожидания импульсов и сообщений и их обработки.
Обратите внимание на проверку значения, возвращаемого MsgReceive — нуль указывает, что был принят импульс (здесь мы не делаем никакой дополнительной проверки, наш ли это импульс), ненулевое значение говорит о том, что было принято сообщение.
Обработка импульсов и сообщений выполняется функциями gotAPulse и gotAMessage.
int main void) // Игнорировать аргументы
// командной строки
{
int rcvid; // PID отправителя
MessageT msg; // Само сообщение
if ((chid = ChannelCreate(0)) == -1) {
fprintf(stderr, "%s: не удалось создать канал!\n",
вы видите код, в котором определяется тип таймера и схема уведомления. Когда мы рассуждали о таймерных функциях выше, я говорил, что таймер может выдать сигнал или импульс, либо создать поток. Решение об этом принимается именно здесь, в функции setupPulseAndTimer. Обратите внимание, что здесь мы использовали макроопределение SIGEV_PULSE_INIT. Используя это макроопределение, мы реально присвоили элементу sigev_notify значение SIGEV_PULSE. (Если бы мы использовали одно из макроопределений семейства SIGEV_SIGNAL*_INIT, мы получили бы уведомление при помощи соответствующего сигнала). Отметьте, что при настройке импульса мы с помощью вызова ConnectAttach устанавливаем соединение с самим собой и даем ему уникальный код (здесь — константа CODE_TIMER; мы ее определили сами)
Последний параметр в инициализации структуры события — это приоритет импульса; здесь мы выбрали SIGEV_PULSE_PRIO_INHERIT (константа, равная -1). Это предписывает ядру не изменять приоритет принимающего импульс потока.
В конце описания функции мы вызываем timer_create для создания таймера в ядре, после чего настраиваем его на срабатывание через одну секунду (поле it_value) и на периодическую перезагрузку односекундными интервалами (поле it_interval). Отметим, что таймер включается только по вызову timer_settime, а не при его создании.
Схема уведомления по типу SIGEV_PULSE — расширение, свойственное только QNX/Neutrino. Концепция импульсов в POSIX отсутствует.
/*
* setupPulseAndTimer
*
* Эта подпрограмма отвечает за настройку импульса, чтобы