sem14 - Средства System V IPC. Семафоры. Разделяемая память. Очереди сообщений. (1114926), страница 4
Текст из файла (страница 4)
Идентификатор очереди сообщений, полученный в результате вызова msgget, указывается в параметре msqid.Выполняемая операция задаётся параметром cmd, который может принимать одно из следующих значений:• IPC_STAT. Получить информацию о данной очереди сообщений. Заполняется переменная, адрес которой указан в параметре buf.
Мы не будем здесь подробно рассматривать эту команду.13• IPC_SET. Изменить некоторые служебные данные очереди сообщений. Для этого впеременную, адрес которой передаётся в параметре buf, записываются новые значения. Эту команду мы также не будем подробно рассматривать.• IPC_RMID.
Немедленно удалить данную очередь сообщений и все связанные с нейструктуры данных. Все процессы, заблокированные на чтении из этой очереди сообщений или записи в эту очередь сообщений, разблокируются, и соответствующие системные вызовы (msgrcv или msgsnd) завершаются с ошибкой EIDRM. Процесс, выполняющий операцию удаления, должен иметь достаточный уровень привилегий, либоего эффективный идентификатор пользователя должен совпадать с идентификаторомсоздателя или владельца очереди сообщений.При успешном завершении возвращается 0, а при неуспешном — -1, и в переменнуюerrno записывается код возникшей ошибки.EACCESEFAULTEIDRMEINVALEPERMАргумент cmd равен IPC_STAT, но процесс не имеет прав на чтение из очереди сообщений.Аргумент cmd равен IPC_SET или IPC_STAT, но в параметре buf передан недопустимый адрес.Очередь сообщений уже помечена на удаление.Аргументы cmd или msqid содержат недопустимое значение.Аргумент cmd равен IPC_SET или IPC_RMID, но процесс не имеет достаточно привилегий для выполнения этой команды.3.3 Запись в очередь сообщенийДобавить сообщение в очередь сообщений можно с помощью системного вызоваmsgsnd.#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg);Данный системный вызов добавляет копию сообщения, адрес которого передан в аргумента msgp, в очередь сообщений с идентификатором, переданным в аргумент msqid.Чтобы добавить сообщение в очередь процесс должен создать структуру следующего общего вида:struct msgbuf {long mtype;char mtext[0];};/* тип сообщения, должен быть > 0 *//* данные */Поле mtext — это массив или другая структура данных, размер которой задаётся в параметре msgsz.
Допускаются сообщения нулевой длины, то есть без поля mtext. В полеmtype записывается тип сообщения — положительное целое число, которое может использоваться при чтении из очереди сообщений для фильтрации сообщений.Размер сообщения не должен превышать константы MSGMAX, конкретное значение которой зависит от реализации. Например, в ядре Linux она равна 8192 байт.Для успешной записи процесс должен иметь права на запись в очередь сообщений.14Если в буфере очереди сообщений достаточно места для нового элемента, msgsndуспешно завершается без ожидания. Ёмкость очереди сообщений задаётся полемmsg_bytes служебной структуры данных очереди. Исходное значение этого поля присоздании очереди сообщений равно MSGMNB, но оно может быть изменено с помощьюсистемного вызова msgctl, если процесс имеет суперпользовательские полномочия.Значение константы MSGMNB зависит от реализации.
В ядре Linux эта константа равна 16384байтам.Если места для нового элемента в очереди сообщений недостаточно, msgsnd блокирует процесс до тех пор, пока не освободиться достаточно места. Однако, если в аргументеmsgflg установлен флаг IPC_NOWAIT, то при отсутствии места в очереди сообщений системный вызов завершится немедленно с ошибкой EAGAIN.Если вызов msgsnd заблокировал процесс, он может также завершиться в следующихслучаях.• Очередь сообщений удалена с помощью вызова msgctl. В этом случае возвращаетсяошибка EIDRM.• Процессу был доставлен сигнал. В этом случае возвращается ошибка EINTR. Системный вызов msgsnd никогда не перезапускается, если был прерван поступлением сигнала, даже если флаг SA_RESTART был задан при установке обработчика сигнала.При успешном завершении msgsnd возвращает 0, а при ошибке — -1, и в переменнуюerrno записывается код ошибки.
Возможные коды ошибок приведены ниже.EAGAINEACCESEFAULTEIDRMEINTREINVALENOMEMСообщение не может быть добавлено в очередь, так как в данный момент в очерединет достаточно места, и флаг IPC_NOWAIT указан в аргументе msgflg.Процесс не имеет прав записи в данную очередь сообщений.В аргументе msgp передан недопустимый адрес.Очередь сообщений была удалена.При ожидании освобождения места в очереди процесс получил и обработал сигнал.Недопустимое значение аргумента msqid или неположительное значение поляmtype, или недопустимое значение аргумента msgsz (меньшее чем 0 или большеечем MSGMAX).У ядра недостаточно памяти, чтобы сделать копию сообщения msgbuf.3.4 Чтение из очереди сообщенийДля чтения из очереди сообщений используется функция msgrcv.#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz,long msgtyp, int msgflg);Этот системный вызов считывает одно сообщение из очереди сообщений, идентификатор которой задаётся в аргументе msqid.
Аргумент msgp задаёт адрес буфера для чтениясообщения. После успешного чтения сообщение удаляется из очереди.Аргумент msgsz задаёт максимальный размер в байтах поля mtext переменной, адрескоторой указан аргументом msgp. Если длина сообщения больше, чем значение аргумента msgsz, и у аргумента msgflg установлен флаг MSG_NOERROR, сообщение будет обрезано по заданной длине, и обрезанная часть будет потеряна. Если флаг MSG_NOERROR не15установлен, сообщение не удаляется из очереди, а системный вызов завершается с ошибкойE2BIG.Чтобы считать сообщение из очереди процесс должен создать структуру следующего общего вида:struct msgbuf {long mtype;char mtext[0];};/* тип сообщения, должен быть > 0 *//* данные */Поле mtext — это массив или другая структура данных, размер которой задаётся в параметре msgsz. Допускаются сообщения нулевой длины, то есть без поля mtext.
Если размер первого подходящего сообщения превысит значение аргумента msgsz, системный вызовmsgrcv завершится с ошибкой, или сообщение будет обрезано.Если функция msgrcv завершилась успешно, в поле mtype записывается тип сообщения — положительное целое число, а в поле mtext — содержимое сообщения.Чтобы читать из очереди сообщения, процесс должен иметь права на чтение для своегоэффективного идентификатора пользователя.Аргумент msgtyp задаёт ожидаемый тип сообщения.
Аргумент может принимать следующие значения.• Если msgtyp равен 0, считывается первое сообщение из очереди.• Если msgtyp больше 0, считывается первое сообщение в очереди, тип которого совпадает с msgtyp. Но если в аргументе msgflg установлен флаг MSG_EXCEPT, считывается первое сообщение в очереди, тип которого не совпадает с msgtyp.• Если msgtyp меньше 0, считывается первое сообщение из очереди, тип которого меньше либо равен абсолютному значению аргумента msgtyp.В аргументе msgflg могут быть заданы 0 или более флагов, изменяющих работу системного вызова msgrcv.• IPC_NOWAIT. Если флаг установлен, msgrcv возвращается немедленно с кодомошибки ENOMSG, если сообщение требуемого типа в очереди отсутствует.• MSG_EXCEPT.
Используется вместе с положительным значением аргумента msgtypдля чтения первого сообщения в очереди, тип которого не равен msgtyp.• MSG_NOERROR. Если флаг установлен, сообщение обрезается, если его длина превышает msgsz байт.Если в очереди отсутствует сообщение требуемого типа, и флаг IPC_NOWAIT не былустановлен в аргументе msgflg, процесс блокируется до наступления одного из следующихусловий.• Сообщение требуемого типа помещено в очередь.• Очередь сообщений удалена. В этом случае системный вызов завершается с ошибкойEIDRM.16• Процесс получил и обработал сигнал. В этом случае системный вызов завершаетсяс ошибкой EINTR. Системный вызов msgrcv никогда не перезапускается, если былпрерван поступлением сигнала, даже если флаг SA_RESTART был задан при установкеобработчика сигнала.При успешном завершении системный вызов возвращает действительную длину сообщения, скопированного в поле mtext.
При ошибке возвращается -1, а в переменную errnoзаписывается код ошибки.E2BIGEACCESEFAULTEIDRMEINTREINVALENOMSGДлина сообщения больше, чем значение аргумента msgsz, а флаг MSG_NOERROR варгументе msgflg не установлен.Процесс не имеет прав на чтение из данной очереди сообщений.Недопустимый адрес передан в аргументе msgp.Процесс был заблокирован на ожидании поступления сообщения, но очередь сообщений в это время была удалена.Процесс был заблокирован на ожидании поступления сообщений, но поступил и былобработан сигнал.Недопустимое значение аргумента msgqid, или значение аргумента msgsz меньше0.В аргументе msgflg установлен флаг IPC_NOWAIT, и в очереди сообщений нет сообщения требуемого типа.17.