6.4. Функция msgrcv

6.4. Функция msgrcv

Сообщение может быть считано из очереди с помощью функции msgrcv.

#include <sys/msg.h>

ssize_t msgrcv(int msqid, void *ptr, size_t length, long type, int flag);

/* Возвращает количество данных в сообщении, –1 – в случае ошибки */

Аргумент ptr указывает, куда следует помещать принимаемые данные. Как и для msgsnd, он указывает на поле данных типа long (рис. 4.13), которое непосредственно предшествует полезным данным.

Аргумент length задает размер относящейся к полезным данным части буфера, на который указывает ptr. Это максимальное количество данных, которое может быть возвращено функцией. Поле типа long не входит в эту длину.

Аргумент type определяет тип сообщения, которое нужно считать из очереди:

? если значение type равно 0, возвращается первое сообщение в очереди (то есть при указании типа 0 возвращается старейшее сообщение);

? если тип больше 0, возвращается первое сообщение, тип которого равен указанному;

? если тип меньше нуля, возвращается первое сообщение с наименьшим типом, значение которого меньше либо равно модулю аргумента type.

Рассмотрим пример очереди сообщений, изображенный на рис. 6.1. В этой очереди имеются три сообщения:

? первое сообщение имеет тип 100 и длину 1;

? второе сообщение имеет тип 200 и длину 2;

? третье сообщение имеет тип 300 и длину 3.

Таблица 6.1 показывает, какое сообщение будет возвращено при различных значениях аргумента type.

Таблица 6.1. Возвращаемое сообщение в зависимости от аргумента type 

type Тип возвращаемого сообщения 0 100 100 100 200 200 300 300 -100 100 -200 100 -300 100 

Аргумент flag указывает, что делать, если в очереди нет сообщения с запрошенным типом. Если установлен бит IPC_NOWAIT, происходит немедленный возврат из функции msgrcv с кодом ошибки ENOMSG. В противном случае вызвавший процесс блокируется до тех пор, пока не произойдет одно из следующего:

? появится сообщение с запрошенным типом;

? очередь с идентификатором msqid будет удалена из системы (в этом случае будет возвращена ошибка с кодом EIDRM);

? вызвавший поток будет прерван перехватываемым сигналом (в этом случае возвращается ошибка EINTR).

В аргументе flag можно указать дополнительный бит MSG_NOERROR. При установке этого бита данные, превышающие объем буфера (аргумент length), будут просто обрезаться до его размера без возвращения кода ошибки. Если этот флаг не указать, при превышении объемом сообщения аргумента length будет возвращена ошибка E2BIG.

В случае успешного завершения работы msgrcv возвращает количество байтов в принятом сообщении. Оно не включает байты, нужные для хранения типа сообщения (long), который также возвращается через указатель ptr.

Данный текст является ознакомительным фрагментом.