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. Он позволяет выполнять следующие управляющие действия:



2004-06-22