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

на главную - закладки

Жанры

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

Кёртен Роб

Шрифт:

Ядро резервирует отрицательные значения параметра code, оставляя 127 значений для программистов — для использования по своему усмотрению.

Элемент value в действительности является элементом типа

union
:

union sigval {

 int sival_int;

 void *sival_ptr;

};

Поэтому (в развитие примера с сервером, представленного выше) вы часто будете видеть программу, подобную

этой:

#include <sys/neutrino.h>

rcvid = MsgReceive(chid, ...

if (rcvid == 0) { // Импульс

 // Определить тип импульса

 switch (msg.pulse.code) {

 case MY_PULSE_TIMER:

// Сработал один из наших таймеров,

// надо что-то делать...

break;

 case MY_PULSE_HWINT:

// Импульс получен от обработчика прерывания.

// Надо заглянуть в поле «value»...

val = msg.pulse.value.sival_int;

// Сделать что-нибудь по этому поводу...

break;

 case _PULSE_CODE_UNBLOCK:

// Это импульс от ядра, разблокирующий клиента

// Сделать что-нибудь по этому поводу...

break;

//и так далее...

 }

} else { // Обычное сообщение

 // Определить тип сообщения

 // Обработать его

}

В этой программе предполагается, конечно, что вы описали структуру msg так, чтобы она содержала элемент «

struct _pulse pulse;
», и что определены константы MY_PULSE_TIMER и MY_PULSE_HWINT. Код импульса _PULSE_CODE_UNBLOCK — один из тех самых отрицательных кодов, зарезервированных для ядра, как это было упомянуто выше. Вы можете найти полный список этих кодов (а также краткое описание поля value) в
<sys/neutrino.h>
.

Функция MsgReceivePulse

Функции MsgReceive и MsgReceivev могут принимать либо стандартное сообщение, либо импульс. Однако, возможны ситуации, когда вы пожелаете принимать только импульсы. Лучшим примером этого является ситуация с сервером, когда вы приняли запрос от клиента на выполнение чего-нибудь, но не можете выполнить этот запрос сразу (возможно, из-за длительной операции, связанной с аппаратными средствами). В таких случаях следует, как правило, настроить аппаратные средства (или таймер, или что-нибудь еще) на передачу вам импульса всякий раз, когда происходит некое значительное событие.

Если вы напишете ваш сервер по стандартной схеме «ждать сообщения

в бесконечном цикле», вы можете оказаться в ситуации, когда один клиент посылает вам запрос, а потом, пока вы ожидаете импульса, который должен сигнализировать об отработке запроса, приходит запрос от другого клиента. Вообще говоря, это как раз то что нужно — в конце концов, мы хотели иметь способность одновременно обслуживать множество клиентов. Однако, у вас могут быть веские основания отказать клиенту в обслуживании — например, если обслуживание клиента слишком ресурсоемко, и надо ограничить численность одновременно обрабатываемой клиентуры.

В таком случае вам потребуется обеспечить возможность «выборочного» приема только импульсов. Тут-то и становится актуальной функция MsgReceivePulse:

#include <sys/neutrino.h>

int MsgReceivePulse(int chid, void *rmsg, int rbytes,

 struct _msg_info *info);

Видно, что ее параметры те же, что и у функции MsgReceive — идентификатор канала, буфер (и его размер), и параметр info — мы обсуждали его в параграфе «Кто послал сообщение?» Заметьте, что параметр info не применяется в импульсах. Вы можете спросить, почему он представлен в списке параметров. Ответ незамысловат: так было проще сделать. Просто передайте NULL!

Функция MgsReceivePulse способна принимать только импульсы. Так, если бы у вас был канал с множеством потоков, блокированных на нем с помощью функции MsgReceivePulse (и ни одного потока, блокированного на нем с помощью функции MsgReceive), и некий клиент попытался бы отправить вашему серверу сообщение, то этот клиент остался бы заблокированным по передаче (Send-blocked) до тех пор, пока какой-либо поток сервера не вызовет MsgReceive. Тем временем функция MsgReceivePulse будет спокойно принимать импульсы.

Единственное, что можно гарантировать при совместном применении функций MsgReceivePulse и MsgReceive, — что функция MsgReceivePulse обеспечит прием исключительно импульсов. Функция MsgReceive сможет принимать как импульсы, так и обычные сообщения! Это происходит потому, что применение функции MsgReceivePulse зарезервировано специально для случаев, где нужно исключить получение сервером обычных сообщений.

Это немного вводит в замешательство. Так как функция MsgReceive может принимать и обычные сообщения, и импульсы, а функция MsgReceivePulse может принимать только импульсы, то как быть с сервером, в котором применяются обе функции? Общий ответ такой. У вас есть пул потоков, выполняющих MsgReceive. Этот пул потоков (один или более потоков — это зависит от числа клиентов, которое вы хотели бы обслуживать одновременно) отвечает за обработку запросов от клиентов.

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

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

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

Бестужев. Служба Государевой Безопасности. Книга четвертая

Измайлов Сергей
4. Граф Бестужев
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бестужев. Служба Государевой Безопасности. Книга четвертая

Светлая тьма. Советник

Шмаков Алексей Семенович
6. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Светлая тьма. Советник

Лисья нора

Сакавич Нора
1. Всё ради игры
Фантастика:
боевая фантастика
8.80
рейтинг книги
Лисья нора

Калибр Личности 5

Голд Джон
5. Калибр Личности
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Калибр Личности 5

(Не)нужная жена дракона

Углицкая Алина
5. Хроники Драконьей империи
Любовные романы:
любовно-фантастические романы
6.89
рейтинг книги
(Не)нужная жена дракона

Сердце Дракона. Том 10

Клеванский Кирилл Сергеевич
10. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.14
рейтинг книги
Сердце Дракона. Том 10

Белые погоны

Лисина Александра
3. Гибрид
Фантастика:
фэнтези
попаданцы
технофэнтези
аниме
5.00
рейтинг книги
Белые погоны

Как я строил магическую империю

Зубов Константин
1. Как я строил магическую империю
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Как я строил магическую империю

Повелитель механического легиона. Том VII

Лисицин Евгений
7. Повелитель механического легиона
Фантастика:
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Повелитель механического легиона. Том VII

Я князь. Книга XVIII

Дрейк Сириус
18. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я князь. Книга XVIII

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

INDIGO
Вселенная EVE Online
Фантастика:
космическая фантастика
5.00
рейтинг книги
На границе империй. Том 10. Часть 2

Вечный. Книга I

Рокотов Алексей
1. Вечный
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Вечный. Книга I

Отморозок 3

Поповский Андрей Владимирович
3. Отморозок
Фантастика:
попаданцы
5.00
рейтинг книги
Отморозок 3