Читаем Операционная система UNIX полностью

Очереди сообщений обладают весьма полезным свойством — в одной очереди можно мультиплексировать сообщения от различных процессов. Для демультиплексирования используется атрибут msgtype, на основании которого любой процесс может фильтровать сообщения с помощью функции msgrcv(2) как это было показано выше.

Рассмотрим типичную ситуацию взаимодействия процессов, когда серверный процесс обменивается данными с несколькими клиентами. Свойство мультиплексирования позволяет использовать для такого обмена одну очередь сообщений. Для этого сообщениям, направляемым от любого из клиентов серверу, будем присваивать значение типа, скажем, равным 1. Если в теле сообщения клиент каким-либо образом идентифицирует себя (например, передает свой PID), то сервер сможет передать сообщение конкретному клиенту, присваивая тип сообщения равным этому идентификатору.

Поскольку функция msgrcv(2) позволяет принимать сообщения определенного типа (типов), сервер будет принимать сообщения с типом 1, а клиенты — сообщения с типами, равными идентификаторам их процессов. Схема такого взаимодействия представлена на рис. 3.19.

Рис. 3.19. Мультиплексирование сообщений в одной очереди

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

Пример приложения "Здравствуй, Мир!", использующего сообщения:

Файл описания mesg.h

#define MAXBUFF 80

#define PERM 0666

/* Определим структуру нашего сообщения. Она может отличаться

   от структуры msgbuf, но должна содержать поле mtype. В данном

   случае структура сообщения состоит из буфера обмена */

typedef struct our msgbuf {

 long mtype;

 char buff[MAXBUFF];

} Message;

Сервер:

#include

#include

#include "mesg.h"

main() {

 /* Структура нашего сообщения (может отличаться от

    структуры msgbuf) */

 Message message;

 key_t key;

 int msgid, length, n;

 /* Получим ключ */

 if ((key = ftok("server", 'A')) < 0) {

  printf("Невозможно получить ключ\n");

  exit(1);

 }

 /* Тип принимаемых сообщений */

 message.mt_type = 1L;

 /* Создадим очередь сообщений */

 if ((msgid = msgget(key, РЕRМ | IPC_CREAT)) < 0) {

  printf("Невозможно создать очередь\n");

  exit(1);

 }

 /* Прочитаем сообщение */

 n =

  msgrcv(msgid, &message, sizeof(message), message.mtype, 0);

 /* Если сообщение поступило, выведем его содержимое

    на терминал */

 if (n > 0) {

  if (write(1, message.buff, n) != n) {

   printf("Ошибка вывода\n");

   exit(1);

  }

 } else {

  printf("Ошибка чтения сообщения\n");

  exit(1);

 }

 /* Удалить очередь поручим клиенту */

 exit(0);

}

Клиент:

#include

#include

#include

#include "mesg.h"

main {

 /* Структура нашего сообщения (может отличаться от

    структуры msgbuf */

 Message message;

 key_t key;

 int msgid, length;

 /* Тип посылаемого сообщения, может использоваться для

    мультиплексирования */

 message.mtype = 1L;

 /* Получим ключ */

 if ((key = ftok("server", 'A')) < 0) {

  printf("Невозможно получить ключ\n");

  exit(1);

 }

 /* Получим доступ к очереди сообщений, очередь уже

    должна быть создана сервером */

 if ((msgid = msgget(key, 0)) < 0) {

  printf("Невозможно получить доступ к очереди\n");

  exit(1);

 }

 /* Поместим строку в сообщение */

 if ((length = sprintf(message.buff,

  "Здравствуй, Мир!\n")) < 0) {

Перейти на страницу:

Похожие книги

Архитектура операционной системы UNIX (ЛП)
Архитектура операционной системы UNIX (ЛП)

Настоящая книга посвящена описанию внутренних алгоритмов и структур, составляющих основу операционной системы (т. н. «ядро»), и объяснению их взаимосвязи с программным интерфейсом. Таким образом, она будет полезна для работающих в различных операционных средах. При работе с книгой было бы гораздо полезнее обращаться непосредственно к исходному тексту системных программ, но книгу можно читать и независимо от него.  Во-вторых, эта книга может служить в качестве справочного руководства для системных программистов, из которого последние могли бы лучше уяснить себе механизм работы ядра операционной системы и сравнить между собой алгоритмы, используемые в UNIX, и алгоритмы, используемые в других операционных системах. Наконец, программисты, работающие в среде UNIX, могут углубить свое понимание механизма взаимодействия программ с операционной системой и посредством этого прийти к написанию более эффективных и совершенных программ.

Морис Дж Бах , Морис Дж. Бах

ОС и Сети, интернет / ОС и Сети / Книги по IT