Очередь сообщений

Очередь сообщений представляет собой некое хранилище типизированных сообщений, организованное по принципу FIFO. Любой процесс может помещать новые сообщения в очередь и извлекать из очереди имеющиеся там сообщения. Каждое сообщение имеет тип, представляющий собой некоторое целое число. Благодаря наличию типов сообщений, очередь можно интерпретировать двояко — рассматривать ее либо как сквозную очередь неразличимых по типу сообщений, либо как некоторое объединение подочередей, каждая из которых содержит элементы определенного типа. Извлечение сообщений из очереди происходит согласно принципу FIFO – в порядке их записи, однако процесс-получатель может указать, из какой подочереди он хочет извлечь сообщение, или, иначе говоря, сообщение какого типа он желает получить – в этом случае из очереди будет извлечено самое «старое» сообщение нужного типа.

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

Для создания новой или для доступа к существующей используется системный вызов msgget:

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/message.h>

int msgget (key_t key, int msgflag)

В случае успеха вызов возвращает положительный дескриптор очереди, который может в дальнейшем использоваться для операций с ней, в случае неудачи -1. Первым аргументом вызова является ключ, вторым – флаги, управляющие поведением вызова.

Функция msgsnd()

Для отправки сообщения используется функция msgsnd():

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

int msgsnd (int msqid, const void *msgp, size_t msgsz, int msgflg)

Ее первый аргумент — идентификатор очереди, полученный в результате вызова msgget(). Второй аргумент — указатель на буфер, содержащий реальные данные и тип сообщения, подлежащего посылке в очередь, в третьем аргументе указывается размер буфера.

В качестве буфера необходимо указывать структуру, содержащую следующие поля (в указанном порядке):

long msgtype — тип сообщения

char msgtext[ ] — данные (тело сообщения)

В заголовочном файле <sys/msg.h> определена константа MSGMAX, описывающая максимальный размер тела сообщения. При попытке отправить сообщение, у которого число элементов в массиве msgtext превышает это значение, системный вызов вернет –1.

Четвертый аргумент данного вызова может принимать значения 0 или IPC_NOWAIT. В случае отсутствия флага IPC_NOWAIT вызывающий процесс будет блокирован (т.е. приостановит работу), если для посылки сообщения недостаточно системных ресурсов, т.е. если полная длина сообщений в очереди будет больше максимально допустимого. Если же флаг IPC_NOWAIT будет установлен, то в такой ситуации выход из вызова произойдет немедленно, и возвращаемое значение будет равно –1.

В случае удачной записи возвращаемое значение вызова равно 0.

Функция msgrcv()

Для получения сообщения имеется функция msgrcv:

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

int msgrcv (int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg)

msqid – идентификатор очереди

msgp – указатель на буфер

msgsz – размер буфера

msgtyp - тип сообщения, которое процесс желает получить

= 0 любого типа

> 0 типа msgtyp

< 0 наименьшее значение среди типов, которые меньше модуля msgtyp

msgflg – побитовое сложение флагов

IPC_NOWAIT – если сообщения в очереди нет, то возврат –1

MSG_NOERROR – разрешение получать сообщение, даже если его длина превышает емкость буфера

В случае успеха возвращается 0

Функция msgctl()

Функция управления очередью сообщений выглядит следующим образом:

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

int msgctl (int msqid, int cmd, struct msgid_ds *buf)

Данный вызов используется для получения или изменения процессом управляющих параметров, связанных с очередью и уничтожения очереди. Ее аргументы — идентификатор ресурса, команда, которую необходимо выполнить, и структура, описывающая управляющие параметры очереди. Тип msgid_ds описан в заголовочном файле <sys/message.h>, и представляет собой структуру, в полях которой хранятся права доступа к очереди, статистика обращений к очереди, ее размер и т.п.

Возможные значения аргумента cmd:

IPC_STAT – скопировать структуру, описывающую управляющие параметры очереди по адресу, указанному в параметре buf

IPC_SET – заменить структуру, описывающую управляющие параметры очереди, на структуру, находящуюся по адресу, указанному в параметре buf

IPC_RMID – удалить очередь. Как уже говорилось, удалить очередь может только процесс, у которого эффективный идентификатор пользователя совпадает с владельцем или создателем очереди, либо процесс с правами привилегированного пользователя.

В случае успеха возвращается 0.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: