Операционная система UNIX. Руководство программиста

       

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


Перед тем, как посылать или принимать сообщения, должны быть созданы очередь сообщений с уникальным идентификатором и ассоциированная с ней структура данных. Порожденный уникальный идентификатор называется идентификатором очереди сообщений (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(2) установлен только флаг IPC_CREAT, выполняется одно из двух действий:


  • Порождается новый идентификатор msqid и создаются ассоциированные с ним очередь сообщений и структура данных.
  • Возвращается существующий идентификатор msqid, с которым уже ассоциированы очередь сообщений и структура данных.


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



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

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

Более детально использование данного системного вызова обсуждается в пункте Использование msgget.

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



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

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

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


  • Опросить содержимое структуры данных, ассоциированной с идентификатором очереди сообщений msqid.


  • Изменить права на выполнение операций над очередью сообщений.


  • Изменить максимально допустимое число байт (msg_qbytes) в очереди сообщений, определяемой идентификатором msqid.


  • Удалить из системы идентификатор msqid, ликвидировать очередь сообщений и ассоциированную с ней структуру данных.


Более детально системный вызов msgct(2) описан в пункте Управление очередями сообщений.




Содержание раздела