next up previous contents
Next: Создание очередей сообщений Up: Очереди сообщений. Previous: Общие сведения об очередях.   Contents

Использование очередей сообщений

Перед тем, как посылать или принимать сообщения, должны быть созданы очередь сообщений с уникальным идентификатором и ассоциированная с ней структура данных. Порожденный уникальный идентификатор называется идентификатором очереди сообщений (msqid); он используется для обращений к очереди сообщений и ассоциированной структуре данных.

Говоря об очереди сообщений следует иметь в виду, что реально в ней хранятся не сами сообщения, а их описатели, имеющие следующую структуру:

struct msg {

struct msg *msg_next; /* Указатель на следующее сообщение */

long msg_type; /* Тип сообщения */

short msg_ts; /* Размер текста сообщения */

short msg_spot; /* Адрес текста сообщения */

};

Приведенное определение находится во включаемом файле <sys/msg.h>.

С каждым уникальным идентификатором очереди сообщений ассоциирована одна структура данных, которая содержит следующую информацию:

struct msqid_ds {

  struct ipc_perm msg_perm; /* Структура прав на выполнение операций */

  struct msg *msg_first; /* Указатель на первое сообщение в очереди */

  struct msg *msg_last; /* Указатель на последнее сообщение в очереди */

  ushort msg_cbytes; /* Текущее число байт в очереди */

  ushort msg_qnum; /* Число сообщений в очереди */

  ushort msg_qbytes; /* Макс. допустимое число байт в очереди */

  ushort msg_lspid; /* Ид-р последнего отправителя */

  ushort msg_lrpid; /* Ид-р последнего получателя */

  time_t msg_stime; /* Время последнего отправления */

  time_t msg_rtime; /* Время последнего получения */

  time_t msg_ctime; /* Время последнего изменения */

};

Это определение также находится во включаемом файле <sys/msg.h>. Поле структуры msg_perm использует в качестве шаблона структуру ipc_perm, которая задает права на операции с сообщениями и определяется так:

struct ipc_perm {

  ushort uid; /* Идентификатор пользователя */

  ushort gid; /* Идентификатор группы */

  ushort cuid; /* Идентификатор создателя очереди */

  ushort cgid; /* Ид-р группы создателя очереди */

  ushort mode; /* Права на чтение/запись */

  ushort seq; /* Последовательность номеров используемых слотов */

  key_t key; /* Ключ */

};

Последнее определение находится во включаемом файле <sys/ipc.h>, общем для всех средств межпроцессной связи.

Если в аргументе msgflg системного вызова msgget установлен только флаг IPC_CREAT, выполняется одно из двух действий:

Действие определяется по значению аргумента key. Если еще не существует идентификатора msqid со значением ключа key, выполняется первое действие, то есть для данного ключа выделяется новый уникальный идентификатор и создаются ассоциированные с ним очередь сообщений и структура данных (при условии, что не будет превышен соответствующий системный лимит).

Кроме того, можно специфицировать ключ key со значением IPC_PRIVATE. Если указан такой ``личный'' ключ, для него обязательно выделяется новый уникальный идентификатор и создаются ассоциированные с ним очередь сообщений и структура данных (при условии, что это не приведет к превышению системного лимита). При выполнении утилиты ipcs поле KEY для подобного идентификатора msqid из соображений секретности содержит нули.

Если идентификатор msqid со специфицированным значением ключа key уже существует, выполняется второе действие, то есть возвращается ассоциированный идентификатор. Если необходимо считать возвращение существующего идентификатора ошибкой, в передаваемом системному вызову аргументе msgflg нужно установить флаг IPC_EXCL.

При выполнении первого действия процесс, вызвавший msgget, становится владельцем / создателем очереди сообщений; соответственно этому инициализируется ассоциированная структура данных. Напомним, что владелец очереди может быть изменен, однако процесс-создатель всегда остается создателем. При создании очереди сообщений определяются также начальные права на выполнение операций над ней.

После того, как созданы очередь сообщений с уникальным идентификатором и ассоциированная с ней структура данных, можно использовать системные вызовы семейства msgop (операции над очередями сообщений) и msgctl (управление очередями сообщений).

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

Для управления очередями сообщений используется системный вызов msgctl. Он позволяет выполнять следующие управляющие действия:



2003-12-09