Перед тем как посылать или принимать сообщения, должны быть созданы
очередь сообщений с уникальным идентификатором и ассоциированная с
ней структура данных. Порожденный уникальный идентификатор называется
идентификатором очереди сообщений
(msqid); он используется
для обращений к очереди сообщений и ассоциированной структуре данных.
Говоря об очереди сообщений, следует иметь в виду, что реально в ней хранятся не сами сообщения, а их дескрипторы, имеющие следующую структуру:
/* Указатель на следующее сообщение */
struct msg *msg_next;
long msg_type; /* Тип сообщения */
short msg_ts; /* Размер текста сообщения */
short msg_spot; /* Адрес текста сообщения */
};
С каждым уникальным идентификатором очереди сообщений ассоциирована структура данных, которая содержит следующую информацию:
/*Структура прав на выполнение операций*/
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;
};
ushort uid; /* Идентификатор пользователя */
ushort gid; /* Идентификатор группы */
ushort cuid; /* Идентификатор создателя очереди */
ushort cgid; /* Ид-р группы создателя очереди */
ushort mode; /* Права на чтение/запись */
/* Последовательность номеров используемых слотов */
ushort seq;
key_t key; /* Ключ */
};
Если в аргументе msgflg системного вызова msgget установлен только флаг IPC_CREAT, выполняется одно из двух действий:
Кроме того, можно специфицировать ключ key со значением
IPC_PRIVATE.
Если указан такой ``личный'' ключ, для него обязательно выделяется
новый уникальный идентификатор и создаются ассоциированные с ним очередь
сообщений и структура данных (при условии, что это не приведет к превышению
системного лимита). При выполнении утилиты ipcs поле KEY
для подобного идентификатора msqid из соображений секретности
содержит нули.
Если идентификатор msqid со специфицированным значением ключа
key уже существует, выполняется второе действие, т. е.
возвращается ассоциированный идентификатор. Если необходимо
считать
возвращение существующего идентификатора ошибкой, в передаваемом системному
вызову аргументе msgflg нужно установить флаг IPC_EXCL.
При выполнении первого действия процесс, вызвавший msgget, становится владельцем или создателем очереди сообщений; соответственно этому инициализируется ассоциированная структура данных. Впоследствии владелец очереди может быть изменен, однако процесс-создатель всегда остается создателем. При создании очереди сообщений определяются также начальные права на выполнение операций над ней.
После того как созданы очередь сообщений с уникальным идентификатором и ассоциированная с ней структура данных, можно использовать системные вызовы семейства msgop (операции над очередями сообщений) и msgctl (управление очередями сообщений).
Операции, как упоминалось выше, заключаются в посылке и приеме сообщений. Для каждой из этих операций предусмотрен системный вызов, msgsnd() и msgrcv() соответственно.
Для управления очередями сообщений используется системный вызов msgctl. Он позволяет выполнять следующие управляющие действия: