26.5.4. Получение сообщений очереди
26.5.4. Получение сообщений очереди
Для получения сообщения используется системный вызов msgrcv():
int msgrcv(int msqid, struct msgbuf *msgp, int msgsz,
long mtype, int msgflg);
Первый аргумент определяет очередь, из которой нужно получить сообщение. Второй аргумент — это адрес буфера, в который будет записано сообщение. Третий аргумент — это ограничитель длины сообщения. Четвертый аргумент — это тип сообщения. Ядро будет искать в очереди наиболее старое сообщение данного типа и вернет его копию. Если mtype=0, то ядро вернет самое старое сообщение независимо от типа.
После успешного получения сообщения оно удаляется из очереди.
В случае успеха вызов msqrcv() возвращает число байтов, скопированных в буфер, или -1 в случае ошибки. Переменная errno устанавливается следующим образом:
? E2BIG — длина сообщения больше, чем ограничитель msgsz;
? EACCESS — у вас недостаточно прав;
? EFAULT — недоступен адрес буфера;
? EIDRM — очередь уничтожена ядром;
? EINTR — операция прервана поступившим сигналом;
? EINVAL — ошибка в аргументах, например, отрицательный размер сообщения или неверный номер очереди;
? ENOMSG — нет сообщения, удовлетворяющего условию. Посылается, если установлен флаг IPC_NOWAIT, в противном случае процесс будет ждать нужного сообщения.
Последний аргумент предоставляет дополнительные возможности по работе с сообщениями. Если установлен бит MSG_NOERROR в msgflg, то если размер сообщения больше, чем msgsz, оно будет обрезано и вы получите только msgsz байтов. Если флаг MSG_NOERROR не устанавливать, вы получите ошибку E2BIG.
Следующий код получает сообщение из очереди:
int id; /* ID очереди */
int res, length; /* результат операции и длина */
struct my_buf buf; /* буфер */
int type = 1; /* тип сообщения */
length = sizeof(struct my_buf) — sizeof(long);
if ((res =
msgrcv(id, &buf, length, type, 0)) == -1) {
printf("Ошибка!");
/* можно проанализировать ошибку */
if (errno==E2BIG) printf("Сообщение слишком большое ");
if (errno==EACCESS) printf("Heт доступа ");
/* и т.д. */
exit(1);
}
Данный текст является ознакомительным фрагментом.