"%s: не удалось создать таймер, errno %d\n",
progname, errno);
perror(NULL);
exit(EXIT_FAILURE);
}
// Настроить таймер (задержка 1 с, перезагрузка через
// 1 с) ...
timer.it_value.tv_sec = 1;
timer.it_value.tv_nsec = 0;
timer.it_interval.tv_sec = 1;
timer.it_interval.tv_nsec = 0;
// ...и запустить его!
timer_settime(timerid, 0, &timer, NULL);
}
В функции for
), а затем посылаем его по мере необходимости. Этот прием — по существу вопрос стиля: если вы предполагаете отвечать часто, возможно, имело бы смысл выполнить настройку однажды и загодя. Если же множество ответов не ожидается, то имело бы больший смысл делать настройки по мере необходимости.
Если значение оставшегося времени еще не достигло нуля, мы не делаем ничего — клиент по-прежнему заблокирован в ожидании сообщения.
/*
* gotAPulse
*
* Эта подпрограмма отвечает за обработку тайм-аутов.
* Она проверяет список клиентов на предмет тайм-аута
* и отвечает соответствующим сообщением тем клиентам,
* у которых тайм-аут произошел.
*/
void gotAPulse(void) {
ClientMessageT msg;
int i;
if (debug) {
time_t now;
time(&now);
printf("Получен импульс, время %s", ctime(&now));
}
// Подготовить ответное сообщение
msg.messageType = MT_TIMEDOUT;
// Просмотреть список клиентов
for (i = 0; i < MAX_CLIENT; i++) {
// Элемент используется?
if (clients[i].in_use) {
// Тайм-аут?
if (--clients[i].timeout == 0) {
// Ответить
MsgReply(clients[i].rcvid, EOK, &msg, sizeof(msg));
// Освободить элемент
clients[i].in_use = 0;
}
}
}
}
В функции
/*
* gotAMessage
*
* Эта подпрограмма вызывается при каждом приеме
* сообщения. Проверяем тип
* сообщения (либо «жду данных», либо «вот данные»),
* и действуем
* соответственно. Для простоты предположим, что данные
* никогда не ждут.
* Более подробно об этом см. в тексте.
*/
void gotAMessage(int rcvid, ClientMessageT *msg) {
int i;
// Определить тип сообщения
switch (msg->messageType) {
// Клиент хочет ждать данных
case MT_WAIT_DATA:
// Посмотрим, есть ли пустое место в таблице клиентов
for (i = 0; i < MAX_CLIENT; i++) {
if (!clients[i].in_use) {
// Нашли место - пометить как занятое,
// сохранить rcvid
// и установить тайм-аут
clients[i].in_use = 1;
clients[i].rcvid = rcvid;
clients[i].timeout = 5;
return;
}
}
fprintf(stderr,