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



         

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


Для выполнения примитива send используется системный вызов msgsnd(), копирующий пользовательское сообщение в очередь сообщений, заданную IPC-дескриптором. При изучении описания этого вызова обратите особое внимание на следующие моменты:

  • Тип данных struct msgbuf не является типом данных для пользовательских сообщений, а представляет собой лишь шаблон для создания таких типов. Пользователь сам должен создать структуру для своих сообщений, в которой первым полем должна быть переменная типа long, содержащая положительное значение типа сообщения.
  • В качестве третьего параметра – длины сообщения – указывается не вся длина структуры данных, соответствующей сообщению, а только длина полезной информации, т. е. информации, располагающейся в структуре данных после типа сообщения. Это значение может быть и равным 0 в случае, когда вся полезная информация заключается в самом факте прихода сообщения (сообщение используется как сигнальное средство связи).
  • В материалах семинаров мы, как правило, будем использовать нулевое значение флага системного вызова, которое приводит к блокировке процесса при отсутствии свободного места в очереди сообщений.

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

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

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

int msgsnd(int msqid, struct msgbuf *ptr, int length, int flag);

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

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

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

Структура 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. Этот параметр может быть равен и 0, если вся полезная информация заключается в самом факте наличия сообщения. Системный вызов копирует сообщение, расположенное по адресу, на который указывает параметр ptr, в очередь сообщений, заданную дескриптором msqid.

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

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

Системный вызов возвращает значение 0 при нормальном завершении и значение -1 при возникновении ошибки.

<


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