используется при получении сообщения, вы не можете его просто игнорировать. Вы должны включить его в вашу структуру данных, и будет разумно инициализировать его с помощью известного значения.
указатель на отправляемое сообщение, которое должно начинаться с элемента типа
long int
, как описывалось ранее.
Третий параметр
msg_sz
— объем сообщения, на которое указывает
msg_ptr
. Этот объем не должен включать элемент типа
long int
, содержащий тип сообщения.
Четвертый параметр
msgflg
управляет действиями, предпринимаемыми при заполнении текущей очереди сообщений или достижении общесистемного ограничения для очередей сообщений. Если в параметре
msgflg
установлен флаг
IPC_NOWAIT
, функция вернет управление немедленно без отправки сообщения и возвращаемое значение будет равно -1. Если в параметре
msgflg
флаг
IPC_NOWAIT
сброшен, процесс отправки будет приостановлен в ожидании освобождения доступного объема в очереди.
В случае успеха функция вернет 0, а в случае аварийного завершения — -1. Если вызов был успешен, копия данных сообщения принимается и помещается в очередь сообщений.
msgrcv
Функция
msgrcv
извлекает сообщения из очереди сообщений:
int msgrcv(int msqid, void *msg_ptr, size_t msg_sz, long int msgtype, int msgflg);
— указатель на получаемое сообщение, которое должно начинаться с элемента типа
long int
, как описывалось ранее в функции
msgsnd
.
Третий параметр
msg_sz
— размер сообщения, на которое указывает
msg_ptr
, без элемента типа
long int
, содержащего тип сообщения.
Четвертый параметр
msgtype
типа
long int
позволяет реализовать простую форму приоритетного получения. Если значение
msgtype
равно 0, извлекается первое доступное сообщение в очереди. Если значение параметра больше нуля, извлекается первое сообщение с таким же типом сообщения. Если оно меньше нуля, извлекается первое сообщение с таким же типом сообщения или со значением, по абсолютной величине меньшим, чем
msgtype
.
На практике все гораздо проще. Если вы просто хотите получать сообщения в порядке их отправления, задайте
msgtype
, равным 0. Если нужно извлекать сообщения только с определенным типом, задайте
msgtype
, равным этому значению. Если вам необходимо получать сообщения с типом не превышающим
n
, задайте
msgtype
, равным
– n
.
Четвертый параметр
msgflg
управляет действиями в случае отсутствия сообщения подходящего типа, которое ожидает извлечения. Если в параметре
msgflg
установлен флаг
IPC_NOWAIT
, вызов вернет управление программе немедленно с возвращаемым значением -1. Если флаг
IPC_NOWAIT
в
msgflg
сброшен, процесс будет приостановлен в ожидании прибытия сообщения подходящего типа.
В случае успешного завершения функция msgrcv вернет количество байтов, помещенных в буфер приема, сообщение копируется в выделяемый пользователем буфер, на который указывает
msg_ptr
, и данные удаляются из очереди сообщений. В случае ошибки функция вернет -1.
msgctl
Последняя функция обработки очереди сообщений
msgctl
очень похожа на функцию управления для совместно используемой памяти:
int msgctl(int msqid; int command, struct msqid_ds *buf);
Структура
msqid_ds
содержит, как минимум, следующие элементы:
struct msqid_ds {
uid_t msg_perm.uid;
uid_t msg_perm.gid;
mode_t msg_perm.mode;
}
Первый параметр
msqid
— идентификатор, возвращаемый функцией
msgget
.
Второй параметр
command
задает предпринимаемое действие. Он может принимать три значения, перечисленные в табл. 14.3.
Таблица 14.3
Значение
Описание
IPC_STAT
Задает данные в структуре
msqid_ds
, отображающие значения, связанные с очередью сообщений
IPC_SET
Если у процесса есть на это право, это действие устанавливает значения, связанные с очередью сообщений, в соответствии с данными структуры
msqid_ds
IPC_RMID
Удаляет очередь сообщений
В случае успешного завершения возвращает 0, в случае аварийного — -1. Если очередь сообщений удаляется, когда процесс ожидает в функции
msgsnd
или
msgrcv
, функция отправки или получения сообщения завершается аварийно.
Выполните упражнение 14.3.
Упражнение 14.3. Очереди сообщений
Теперь, когда вы познакомились с объявлениями, относящимися к очередям сообщений, можно посмотреть, как они действуют на практике. Как и раньше, вы напишите две программы: msg1.c для получения и msg2.c для отправки сообщений. Вы разрешите обеим программам создавать очередь сообщений, но используете для удаления очереди программу-приемник после того, как она получит последнее сообщение.