• и, наконец, бесконечный цикл ожидания импульсов и сообщений и их обработки.
Обратите внимание на проверку значения, возвращаемого
Обработка импульсов и сообщений выполняется функциями
int main void) // Игнорировать аргументы
// командной строки
{
int rcvid; // PID отправителя
MessageT msg; // Само сообщение
if ((chid = ChannelCreate(0)) == -1) {
fprintf(stderr, "%s: не удалось создать канал!\n",
progname);
perror(NULL);
exit(EXIT_FAILURE);
}
// Настроить импульс и таймер
setupPulseAndTimer();
// Прием сообщений
for(;;) {
rcvid = MsgReceive(chid, &msg, sizeof(msg), NULL));
// Определить, от кого сообщение
if (rcvid == 0) {
// Здесь неплохо бы еще проверить поле «code»...
gotAPulse();
} else {
gotAMessage(rcvid, &msg.msg);
}
}
// Сюда мы никогда не доберемся
return (EXIT_SUCCESS);
}
В функции
Последний параметр в инициализации структуры события — это приоритет импульса; здесь мы выбрали SIGEV_PULSE_PRIO_INHERIT (константа, равная -1). Это предписывает ядру не изменять приоритет принимающего импульс потока.
В конце описания функции мы вызываем
/*
* setupPulseAndTimer
*
* Эта подпрограмма отвечает за настройку импульса, чтобы
* тот отправлял сообщение с кодом MT_TIMER.
* Затем устанавливается
* периодический таймер с периодом в одну секунду.
*/
void setupPulseAndTimer(void) {
timer_t timerid; // Идентификатор таймера
struct sigevent event; // Генерируемое событие
struct itimerspec timer; // Структура данных
// таймера
int coid; // Будем соединяться с
// собой
// Создать канал к себе
coid = ConnectAttach(0, 0, chid, 0, 0);
if (coid == -1) {
fprintf(stderr, "%s: ошибка ConnectAttach!\n", progname);
perror(NULL);
exit(EXIT_FAILURE);
}
// Установить, какое событие мы хотим сгенерировать
// - импульс
SIGEV_PULSE_INIT(&event, coid, SIGEV_PULSE_PRIO_INHERIT,
CODE_TIMER, 0);
// Создать таймер и привязать к событию
if (timer_create(CLOCK_REALTIME, &event, &timerid) ==
-1) {
fprintf(stderr,