Читать «UNIX: взаимодействие процессов» онлайн - страница 94
Уильям Ричард Стивенс
time_t msg_rtime; /* время последнего считывания сообщения */
time_t msg_ctime; /* время последнего вызова msgctl(), изменившего одно из полей структуры */
};
ПРИМЕЧАНИЕ
Unix 98 не требует наличия полей msg_first, msg_last и msg_cbytes. Тем не менее они имеются в большинстве существующих реализаций, производных от System V. Естественно, ничто не заставляет реализовывать очередь сообщений через связный список, который неявно предполагается при наличии полей msg_first и msg_last. Эти два указателя обычно указывают на участки памяти, принадлежащие ядру, и практически бесполезны для приложения.
Мы можем изобразить конкретную очередь сообщений, хранимую ядром как связный список, — рис. 6.1. В этой очереди три сообщения длиной 1, 2 и 3 байта с
В этой главе мы рассмотрим функции, используемые для работы с очередями сообщений System V, и реализуем наш пример файлового сервера из раздела 4.2 с использованием очередей сообщений.
Рис. 6.1. Структура очереди system V в ядре
6.2. Функция msgget
Создать новую очередь сообщений или получить доступ к существующей можно с помощью функции msgget:
#include <sys/msg.h>
int msgget(key_t
/* Возвращает неотрицательный идентификатор в случае успешного завершения, –1 в случае ошибки */
Возвращаемое значение представляет собой целочисленный идентификатор, используемый тремя другими функциями msg для обращения к данной очереди. Идентификатор вычисляется на основе указанного
Флаг
При создании новой очереди сообщений инициализируются следующие поля структуры msqid_ds:
■ полям uid и cuid структуры msg_perm присваивается значение действующего идентификатора пользователя вызвавшего процесса, а полям gid и cgid — действующего идентификатора группы;
■ разрешения чтения-записи, указанные в oflag, помещаются в msg_perm.mode;
■ значения msg_qnum, msg_lspid, msg_lrpid, msg_stime и msg_rtime устанавливаются в 0;
■ в msg_ctime записывается текущее время;
■ в msg_qbytes помещается системное ограничение на размер очереди.
6.3. Функция msgsnd
После открытия очереди сообщений с помощью функции msgget можно помещать сообщения в эту очередь с помощью msgsnd.
#include <sys/msg.h>
int msgsnd(int
/* Возвращает 0 в случае успешного завершения; –1 – в случае ошибки */
Здесь
struct msgbuf {
long mtype; /* тип сообщения, должен быть > 0 */
char mtext[1]; /* данные */
};
Тип сообщения должен быть больше нуля, поскольку неположительные типы используются в качестве специальной команды функции msgrcv, о чем рассказывается в следующем разделе.