Основы операционных систем. Практикум



         

Реализация примитивов send и receive. Системные вызовы msgsnd() и msgrcv() - часть 2


/p>

Примитив receive реализуется системным вызовом msgrcv(). При изучении описания этого вызова нужно обратить особое внимание на следующие моменты:

  • Тип данных struct msgbuf, как и для вызова msgsnd(), является лишь шаблоном для пользовательского типа данных.
  • Способ выбора сообщения (см. раздел "Очереди сообщений в UNIX как составная часть System V IPC" текущего семинара) задается нулевым, положительным или отрицательным значением параметра type. Точное значение типа выбранного сообщения можно определить из соответствующего поля структуры, в которую системный вызов скопирует сообщение.
  • Системный вызов возвращает длину только полезной части скопированной информации, т. е. информации, расположенной в структуре после поля типа сообщения.
  • Выбранное сообщение удаляется из очереди сообщений.
  • В качестве параметра length указывается максимальная длина полезной части информации, которая может быть размещена в структуре, адресованной параметром ptr.
  • В материалах семинаров мы будем, как правило, пользоваться нулевым значением флагов для системного вызова, которое приводит к блокировке процесса в случае отсутствия в очереди сообщений с запрошенным типом и к ошибочной ситуации в случае, когда длина информативной части выбранного сообщения превышает длину, специфицированную в параметре length.

Системный вызов msgrcv()

Прототип системного вызова

#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h>

int msgrcv(int msqid, struct msgbuf *ptr, int length, long type, int flag);

Описание системного вызова

Системный вызов msgrcv предназначен для получения сообщения из очереди сообщений, т. е. является реализацией примитива receive.

Способ выборкиЗначение параметра type
В порядке FIFO, независимо от типа сообщения0
В порядке FIFO для сообщений с типом n n
Первым выбирается сообщение с минимальным типом, не превышающим значения n, пришедшее ранее всех других сообщений с тем же типом-n

Параметр msqid является дескриптором System V IPC для очереди, из которой должно быть получено сообщение, т. е. значением, которое вернул системный вызов msgget() при создании очереди или при ее поиске по ключу.

Параметр type определяет способ выборки сообщения из очереди следующим образом

Структура struct msgbuf описана в файле <sys/msg.h> как

struct msgbuf { long mtype; char mtext[1]; };

Она представляет собой некоторый шаблон структуры сообщения пользователя. Сообщение пользователя – это структура, первый элемент которой обязательно имеет тип long и содержит тип сообщения, а далее следует информативная часть теоретически произвольной длины (практически в Linux она ограничена размером 4080 байт и может быть еще уменьшена системным администратором), содержащая собственно суть сообщения. Например:

struct mymsgbuf { long mtype; char mtext[1024]; } mybuf;

При этом информация вовсе не обязана быть текстовой, например:

struct mymsgbuf { long mtype; struct { int iinfo; float finfo; } info; } mybuf;

Параметр length должен содержать максимальную длину полезной части информации (т. е. информации, расположенной в структуре после типа сообщения), которая может быть размещена в сообщении.

В случае удачи системный вызов копирует выбранное сообщение из очереди сообщений по адресу, указанному в параметре ptr, одновременно удаляя его из очереди сообщений.

Параметр flag может принимать значение 0 или быть какой-либо комбинацией флагов IPC_NOWAIT и MSG_NOERROR. Если флаг IPC_NOWAIT не установлен и очередь сообщений пуста или в ней нет сообщений с заказанным типом, то системный вызов блокируется до появления запрошенного сообщения. При установлении флага IPC_NOWAIT системный вызов в этой ситуации не блокируется, а констатирует возникновение ошибки с установлением значения переменной errno, описанной в файле <errno.h>, равным EAGAIN. Если действительная длина полезной части информации в выбранном сообщении превышает значение, указанное в параметре length и флаг MSG_NOERROR не установлен, то выборка сообщения не производится, и фиксируется наличие ошибочной ситуации. Если флаг MSG_NOERROR установлен, то в этом случае ошибки не возникает, а сообщение копируется в сокращенном виде.

Возвращаемое значение

Системный вызов возвращает при нормальном завершении действительную длину полезной части информации (т. е. информации, расположенной в структуре после типа сообщения), скопированной из очереди сообщений, и значение -1 при возникновении ошибки.

Максимально возможная длина информативной части сообщения в операционной системе Linux составляет 4080 байт и может быть уменьшена при генерации системы. Текущее значение максимальной длины можно определить с помощью команды

ipcs -l




Содержание  Назад  Вперед