Механизм сообщений похож на механизм сообщений, используемый в графических многооконных средах. Каждая группа процессов может создать одну или несколько очередей для обмена сообщениями. Сообщение определяется как «последовательность байтов, передаваемая от одного процесса другому». Система сообщений SVID обладает следующими свойствами:
Возможность накопления сообщений в очереди. Приложения, использующие сообщения для обмена данными, создают свою собственную очередь сообщений, которая может (и должна) быть удалена приложением-владельцем в момент завершения его работы.
Возможность произвольного выбора сообщений из очереди на основе назначенных им идентификаторов. Эта возможность позволяет организовать приоритетную обработку сообщений, а также идентифицировать сообщения, посылаемые разными приложениями, участвующими в обмене данными.
Максимальный размер сообщения и максимальное количество сообщений в очереди ограничены, причем не существует единого для всех Unix-систем способа определить эти ограничения. Максимальная длина сообщения в байтах задана константой MSGMAX,
определенной в файле <linux/msg.h>, а максимальное число сообщений – константой MSGMNG из того же файла.
Структура данных, использующаяся для передачи сообщений, может быть определена следующим образом:
struct msgp {
long mtype;
... // Любые другие поля
};
Поле mtype является единственным обязательным полем в этой структуре. В нем хранится произвольный идентификатор сообщения, который может интерпретироваться как тип передаваемых данных. Кроме поля mtype структура данных сообщения может содержать любое количество других полей любых типов.
Для того чтобы программы могли обмениваться сообщениями, они должны использовать один и тот же формат сообщений и идентификатор очереди.
Очередь сообщений создается при помощи функции msgget():
1 - Ключ очереди представлен числом, поэтому его можно спутать с другим числом – идентификатором очереди, который присваивает система. Ключ нужен только для открытия очереди, а для работы с ней используется идентификатор.
2 - Второй параметр представляет собой комбинацию маски прав доступа к создаваемой очереди (аналогичной маске прав доступа к именованным каналам)
3 - Дополнительные флаги - играет роль только при создании новой очереди сообщений и определяет права различных пользователей при доступе к очереди: флаг IPC_CREAT указывает, что в результате вызова msgget() должна быть создана новая очередь. При установке флага IPC_EXCL, функция msgget() вернет сообщение об ошибке, если очередь с указанным ключом уже существует. В случае успеха msgget() возвращает положительное значение – идентификатор созданной очереди. Он является некоторой комбинацией (с помощью операции побитовое или – "|") следующих предопределенных значений и восьмеричных прав доступа:
IPC_CREAT — если очереди для указанного ключа не существует, она должна быть создана;
IPC_EXCL — применяется совместно с флагом IPC_CREAT. При совместном их использовании и существовании массива с указанным ключом доступ к очереди не производится и констатируется ошибочная ситуация, при этом переменная errno, описанная в файле <errno.h>, примет значение EEXIST;
0400 — разрешено чтение для пользователя, создавшего очередь;
0200 — разрешена запись для пользователя, создавшего очередь;
Передача и получение сообщений выполняется при помощи функций msgsnd(id,msgp,size,flag) и msgrcv(id,msgp,size,type,flag) соответственно.
1 - Первым параметром обеих функций является идентификатор очереди, возвращенный функцией msgget().
2 - Во втором параметре передается размер структуры сообщения. Как было сказано выше, программа, читающая сообщения из очереди, должна указать размер сообщения, соответствующий ожидаемому идентификатору и может читать сообщения разного размера (речь идет о ситуации, когда программа ждет сообщений определенного типа).
3 - Третьим параметром функции msgrcv() является идентификатор сообщения. Если значение этого параметра больше нуля, из очереди будет извлечено сообщение с соответствующим значением поля mtype. Если этот параметр равен нулю, из очереди будет извлечено первое по порядку сообщение, а если параметр отрицательный, из очереди будет извлечено первое сообщение, чей идентификатор меньше либо равен абсолютному значению параметра.
4 - Последний параметр в функциях msgsnd() и msgrcv() позволяет задать дополнительные флаги. Обычно функция, читающая сообщение из очереди, приостанавливает выполнение программы до тех пор, пока не будет извлечено сообщение ожидаемого типа. Именно так работает эта функция в наших программах. При указании флага IPC_NOWAIT функция msgrcv() вернет сообщение об ошибке, если на момент ее вызова в очереди отсутствует подходящее сообщение.
Для удаления очереди используется функция msgctl(id,cmd,buf), которая, как и все функции *ctl(), может выполнять множество разных действий (например, получение данных о состоянии очереди).
1-Первый параметр этой функции, это идентификатор очереди
2-второй параметр – команда (IPC_STAT, IPC_SET или IPC_RMID).
3-Третий параметр используется в вызовах-запросах (то есть, когда второй параметр равен IPC_STAT), а также для конфигурации очереди (команда IPC_SET). В нем передается указатель на структуру msgid_ds, поля которой содержат значения различных параметров очереди. Функция возвращает статус выполнения команды.