Чтение онлайн

на главную

Жанры

Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform

Кёртен Роб

Шрифт:

 if (timer_create(CLOCK_REALTIME, &event, &timerid) ==

– 1) {

fprintf(stderr,

"%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);

}

gotAPulse

В функции gotAPulse вы можете видеть, как мы реализовали способность сервера обеспечивать тайм-ауты для клиентов. Мы последовательно просматриваем список клиентуры и, поскольку мы знаем, что импульс выдается один раз в секунду, просто уменьшаем число секунд, которое остается клиенту до тайм-аута. Если эта величина достигает нулевого значения, мы отвечаем этому клиенту сообщением «Извините, тайм-аут» (тип сообщения MT_TIMEDOUT). Обратите внимание, что мы подготавливаем это сообщение заранее (вне цикла

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

В

функции gotAMessage вы видите другую половину заданной функциональности, где мы добавляем клиента в список клиентуры, ожидающей данные (если получено сообщение типа MT_WAIT_DATA), или сопоставляем клиента с сообщением, которое было только что получено (если это сообщение типа MT_SEND_DATA). Заметьте, что для простоты мы здесь не реализуем очередь клиентов, находящихся в ожидании передачи данных, получатель для которых еще не доступен — это вопрос управления очередями, оставьте его для себя в качестве упражнения.

/*

 * 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,

"Таблица переполнена, сообщение от rcvid %d"

" игнорировано, клиент заблокирован\n", rcvid);

break;

// Клиент с данными

 case MT_SEND_DATA:

// Посмотрим, есть ли другой клиент, которому можно ответить

// данными от этого клиента

for (i = 0; i < MAX CLIENT; i++) {

if (clients[i].in_use) {

// Нашли - использовать полученное сообщение

// в качестве ответного

msg->messageType = MT_OK;

// Ответить ОБОИМ КЛИЕНТАМ!

Поделиться:
Популярные книги

Ученичество. Книга 1

Понарошку Евгений
1. Государственный маг
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Ученичество. Книга 1

Матабар III

Клеванский Кирилл Сергеевич
3. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар III

Кодекс Охотника. Книга XXIII

Винокуров Юрий
23. Кодекс Охотника
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга XXIII

Вопреки судьбе, или В другой мир за счастьем

Цвик Катерина Александровна
Любовные романы:
любовно-фантастические романы
6.46
рейтинг книги
Вопреки судьбе, или В другой мир за счастьем

Идеальный мир для Лекаря 23

Сапфир Олег
23. Лекарь
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Идеальный мир для Лекаря 23

Довлатов. Сонный лекарь

Голд Джон
1. Не вывожу
Фантастика:
альтернативная история
аниме
5.00
рейтинг книги
Довлатов. Сонный лекарь

Мама из другого мира. Дела семейные и не только

Рыжая Ехидна
4. Королевский приют имени графа Тадеуса Оберона
Любовные романы:
любовно-фантастические романы
9.34
рейтинг книги
Мама из другого мира. Дела семейные и не только

Великий род

Сай Ярослав
3. Медорфенов
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Великий род

Проданная Истинная. Месть по-драконьи

Белова Екатерина
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Проданная Истинная. Месть по-драконьи

Треск штанов

Ланцов Михаил Алексеевич
6. Сын Петра
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Треск штанов

Лучший из худших

Дашко Дмитрий
1. Лучший из худших
Фантастика:
фэнтези
попаданцы
5.25
рейтинг книги
Лучший из худших

На границе империй. Том 8. Часть 2

INDIGO
13. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 8. Часть 2

Гром над Академией Часть 3

Машуков Тимур
4. Гром над миром
Фантастика:
фэнтези
5.25
рейтинг книги
Гром над Академией Часть 3

Сила рода. Том 3

Вяч Павел
2. Претендент
Фантастика:
фэнтези
боевая фантастика
6.17
рейтинг книги
Сила рода. Том 3