Рассмотрим реализацию этого механизма в ОС Linux.
Как было сказано ранее, для работы в Linux доступен набор примитивов.
Структура для описания сообщения называется msgbuf; и объявлена в linux/msg.h
/* message buffer for msgsnd and msgrcv calls */
struct msgbuf {
long mtype; /* type of message */
char mtext[1]; /* message text */
};
Поле mtype описывает тип сообщения и всегда имеет положительное значение: соответствие между типами сообщений и их числовым представлением необходимо определить заранее – это часть протокола.
Второе поле представляет само сообщение. Структура msgbuf может быть переопределена и содержать более сложные данные; например ее можно определить так:
struct message {
long mtype; /* message type */
long sender; /* sender id */
long receiver; /* receiver id */
struct info data; /* message content */
...
};
Прототип сообщения может иметь максимальный размер до 4056 байт. Естественно, можно перекомпилировать ядро и увеличить это значение, но, тогда приложение станет непереносимым.
Для создания новой очереди процесс использует функцию msgget()
int msgget(key_t key, int msgflg)
в которую необходимо передать аргументы и IPC ключ, который можно установить в
IPC_CREAT | 0660
( создать очередь, если она еще не существует и предоставить доступ владельцу и группе 'users' ). Эта функция возвращает идентификатор очереди.
Чтобы послать сообщение в очередь, зная ее идентификатор, необходимо использовать функцию msgsnd()
int msgsnd(int msqid, struct msgbuf *msgp, int msgsz, int msgflg)
где msqid идентификатор очереди, msgp указатель на сообщение, которое мы хотим послать (тип которого определен как struct msgbuf но который мы переопределили), msgsz размер сообщения (исключая длину mtype типа long, т.е. 4 байта) и msgflg флаг правила ожидания. Размер сообщения достаточно просто получить, используя следующее выражение:
length = sizeof(struct message) - sizeof(long);
что касается правила ожидания в случае полной очереди: если msgflg установлен в IPC_NOWAIT посылающий сигнал процесс не будет ждать освобождения очереди, и выйдет с кодом ошибки.
Чтобы прочитать сообщения, находящиеся в очереди необходимо использовать системную функцию msgrcv()
int msgrcv(int msqid, struct msgbuf *msgp, int msgsz, long mtype, int msgflg)
где msgp указатель на буфер, в котором мы будем читать сообщения, а mtype определяет список интересующих нас сообщений.
Удаление очереди осуществляется вызовом функции msgctl() с флагом
IPC_RMID
msgctl(qid, IPC_RMID, 0)
Дата добавления: 2015-03-26; просмотров: 499;