Читать «UNIX: взаимодействие процессов» онлайн - страница 80

Уильям Ричард Стивенс

18 };

19 /* один mymsg_hdr{} в начале каждого сообщения */

20 struct mymsg_hdr {

21  long msg_next; /* индекс следующего сообщения в списке */

22                 /* msg_next должно быть первым полем в структуре */

23  ssize_t msg_len; /* реальная длина */

24  unsigned int msg_prio; /* приоритет */

25 };

26 /* одна mymq_info{} выделяется при каждом mq_open() */

27 struct mymq_info {

28  struct mymq_hdr *mqi_hdr; /* начало отображаемого файла */

29  long mqi_magic; /* магическое значение после инициализации */

30  int mqi_flags; /* флаги для данного процесса */

31 };

32 #define MQI_MAGIC 0x98765432

33 /* размер сообщения округляется для подгонки */

34 #define MSGSIZE(i) ((((i) + sizeof(long)-1) / sizeof(long)) * sizeof(long)) 

Рис. 5.2. Схема структур данных, используемых при реализации очередей сообщений posix через отображаемый в память файл 

Структура mq_hdr

8-18 Эта структура хранится в самом начале отображаемого файла и содержит всю информацию об очереди. Поле mq_flags структуры mqh_attr не используется, поскольку флаги (единственный определенный флаг используется для отключения блокировки) должны обрабатываться для каждого открывающего очередь процесса в отдельности, а не для очереди в целом. Поэтому флаги хранятся в структуре mq_info. О прочих полях этой структуры мы будем говорить в связи с их использованием различными функциями.

Обратите внимание, что все переменные, называемые нами индексными (поля этой структуры mqh_head и mqh_free, а также поле msg_next следующей структуры), содержат индексы байтов относительно начала отображаемого в память файла. Например, размер структуры mq_hdr в системе Solaris 2.6 — 96 байт, поэтому индекс первого сообщения, располагающегося сразу за заголовком, имеет значение 96. Каждое сообщение на рис. 5.2 занимает 20 байт (12 байт на структуру msg_hdr и 8 байт на данные), поэтому индексы следующих трех сообщений имеют значения 116, 136 и 156, а размер отображаемого в память файла — 176 байт. Индексы используются для обработки двух связных списков, хранящихся в этом файле: в одном из списков (mqh_head) хранятся все сообщения, имеющиеся в данный момент в очереди, а в другом (mqh_free) — все незаполненные сообщения. Мы не можем использовать настоящие указатели на области памяти (адреса) при работе со списком, поскольку отображаемый файл может находиться в произвольной области памяти для каждого из процессов, работающих с ним (как показано в листинге 13.5).

Структура msg_hdr

19-25 Эта структура располагается в начале каждого сообщения в отображаемом файле. Любое сообщение может принадлежать либо к списку заполненных, либо к списку свободных сообщений, и поле msg_next содержит индекс следующего сообщения в этом списке (или 0, если сообщение является в этом списке последним). Переменная msg_len хранит реальную длину данных в сообщении, которая в нашем примере с рис. 5.2 может иметь значение от 0 до 7 байт включительно. В переменную msg_prio отправителем помещается значение приоритета сообщения.

Структура mq_info