
- •Определение идентификаторов узла, процесса и канала (nd/pid/chid) нужного сервера.
- •Обмен длинными сообщениями
- •Обмен составными сообщениями
- •Сообщения типа «импульс» (pulse)
- •Функция MsgDeliverEvent()
- •Флаги канала
- •Обмен сообщениями в сети
- •Преимущества очередей сообщений стандарта posix
- •Функция Описание
- •Именованные каналы
Сообщения типа «импульс» (pulse)
Импульс — это миниатюрное асинхронное сообщение, которое:
• может перенести 40 бит полезной информации (8-битный код и 32 бита данных);
• является неблокирующим для отправителя;
• может быть получено точно так же, как и сообщение другого типа;
• ставится в очередь, если получатель не заблокирован в ожидании сообщения.
Функция MsgSendPulse() имеет всего 4 параметра
MsgSendPulse (coid, priority, code, data);
code - 8-битный - причина, по которой был отправлен импульс;
data - 32 бита данных, ассоциируемых с данным импульсом.
Ядро резервирует отрицательные значения параметра code, оставляя 127 значений для программистов — для использования по своему усмотрению.
Функция MsgReceivePulse() имеет то же число параметров, что и у функция MsgReceive(). Для приема сервер должен вызвать:
rcvid = MsgReceivePulse (chid, &Pulse, sizeof (Pulse), NULL); или
rcvid = MsgReceive (chid, &Pulse, sizeof (Pulse), NULL);
Но для импульса всегда rcvid = 0.
Возможный код для приема импульса в этом случае следующий:
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 MY_PULSE_CODE_UNBLOCK:
// Это импульс от ядра, разблокирующий клиента.
// Сделать чего-нибудь по этому поводу.
break;
// и так далее …………..
}
else { //Обычное сообщение
// Определить тип сообщения
// Обработать его
}
Функция MsgDeliverEvent()
Существуют ситуации, когда приходится нарушать естественное направление передач.
Такой случай возможен, когда есть клиент, который посылает серверу сообщение и при этом не хочет блокироваться, а результат может быть доступен только через некоторое время.
Для отправки сообщения клиенту без нарушения иерархического принципа необходимо выполнить следующее:
1 Клиент должен создать структуру типа struct sigevent
2 Клиент должен послать сообщение серверу с указанием разблокировать, а по окончании работы уведомить при помощи структуры struct sigevent.
3 Сервер принимает сообщение, включающее в себя структуру struct sigevent, сохраняет структуру struct sigevent и идентификатор отправителя и немедленно отвечает клиенту MsgReply().
4 Далее клиент выполняется — как и сервер.
5 Сервер по окончанию работы использует функцию MsgDeliverEvent(), чтобы сообщить об этом клиенту.
Функция MsgDeliverEvent() принимает два параметра — идентификатор отправителя (rcvid) и доставляемое событие (event).
int MsgDeliverEvent(rcvid, const struct sigevent *event );
Вызывая MsgDeliverEvent(), сервер не блокируется — для сервера это неблокирующий вызов. Ядро доставляет событие клиенту, после чего тот выполняет какие бы то ни было соответствующие действия.