Чтение онлайн

на главную

Жанры

UNIX: взаимодействие процессов

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

Шрифт:

В листинге 5.16 приведен заголовочный файл mqueue.h, определяющий основные структуры, используемые в этой реализации.

Тип mqd_t

Дескриптор нашей очереди сообщений является просто указателем на структуру mq_infо. Каждый вызов mq_open выделяет память под одну такую структуру, а вызвавшему возвращается указатель на нее. Повторим, что дескриптор очереди сообщений не обязательно является небольшим целым числом, как дескриптор файла — единственное ограничение, накладываемое Posix, заключается в том, что этот тип данных не может быть массивом.

Листинг 5.16. Заголовочный файл mqueue.h

//my_pxmsg_mmap/mqueue.h

1 typedef struct mymq_info *mymqd_t;

2 struct mymq_attr {

3 long mq_flags; /* флаг очереди : O_NONBLOCK */

4 long mq_maxmsg; /* максимальное количество сообщений в очереди */

5 long mq_msgsize; /* максимальный размер сообщения в байтах */

6 long mq_curmsgs; /* количество сообщений в очереди */

7 };

8 /* одна структура mymq_hdr{} на очередь, в начале отображаемого файла */

9 struct mymq_hdr {

10 struct mymq_attr mqh_attr; /* атрибуты очереди */

11 long mqh_head; /* индекс первого сообщения*/

12 long mqh_free; /* индекс первого пустого сообщения */

13 long mqh_nwait; /* количество заблокированных mq_receive потоков */

14 pid_t mqh_pid; /* ненулевой PID. если включено уведомление */

15 struct sigevent mqh_event; /* для mq_notify */

16 pthread_mutex_t mqh_lock; /* блокировка: mutex*/

17 pthread_cond_t mqh_wait; /* и условная переменная */

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

26-32 Экземпляр такой структуры динамически создается функцией mq_open при открытии очереди и удаляется mq_close. Поле mqi_hdr указывает на отображаемый файл (адрес начала файла возвращается mmap). Указатель на эту структуру имеет основной в нашей реализации тип mqd_t, он принимает значение, возвращаемое mq_open.

Поле mqi_magiс принимает значение MQI_MAGIC в момент инициализации структуры. Это значение проверяется всеми функциями, которым передается указатель типа mqd_t, что дает им возможность удостовериться, что указатель действительно указывает на структуру типа mq_infо. mqi_flags содержит флаг отключения блокировки для открывшего очередь процесса.

Макрос MSGSIZE

33-34 В целях выравнивания содержимого файла (alignment) мы располагаем начало каждого сообщения так, чтобы его индекс был кратен размеру длинного целого. Следовательно, если максимальный размер сообщения не допускает такого выравнивания, мы добавляем к нему от 1 до 3 байт, как показано на рис. 5.2. При этом предполагается, что размер длинного целого — 4 байт (что верно для Solaris 2.6). Если размер длинного целого 8 байт (в Digital Unix 4.0B), нам придется добавлять к каждому сообщению от 1 до 7 байт.

Поделиться:
Популярные книги

Deus vult

Рокотов Алексей
3. Путь князя
Фантастика:
фэнтези
рпг
попаданцы
5.00
рейтинг книги
Deus vult

Князь Мещерский

Дроздов Анатолий Федорович
3. Зауряд-врач
Фантастика:
альтернативная история
8.39
рейтинг книги
Князь Мещерский

Новые горизонты

Лисина Александра
5. Гибрид
Фантастика:
попаданцы
технофэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Новые горизонты

Барон обходит правила

Ренгач Евгений
14. Закон сильного
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Барон обходит правила

Я еще барон. Книга III

Дрейк Сириус
3. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я еще барон. Книга III

Менталист. Эмансипация

Еслер Андрей
1. Выиграть у времени
Фантастика:
альтернативная история
7.52
рейтинг книги
Менталист. Эмансипация

Мир в латах (сборник)

Полякова Татьяна Викторовна
Фантастика:
социально-философская фантастика
научная фантастика
5.00
рейтинг книги
Мир в латах (сборник)

Неучтенный элемент. Том 2

NikL
2. Антимаг. Вне системы
Фантастика:
городское фэнтези
фэнтези
5.00
рейтинг книги
Неучтенный элемент. Том 2

Печать пожирателя 5

Соломенный Илья
5. Пожиратель
Фантастика:
городское фэнтези
аниме
сказочная фантастика
попаданцы
5.00
рейтинг книги
Печать пожирателя 5

Ювелирные дела

Назимов Константин Геннадьевич
8. Травник
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Ювелирные дела

Неудержимый. Книга XI

Боярский Андрей
11. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга XI

Я до сих пор царь. Книга XXXII

Дрейк Сириус
32. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я до сих пор царь. Книга XXXII

Я уже князь. Книга XIX

Дрейк Сириус
19. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.50
рейтинг книги
Я уже князь. Книга XIX

Геном хищника. Книга четвертая

Гарцевич Евгений Александрович
4. Я - Легенда!
Фантастика:
боевая фантастика
рпг
попаданцы
5.00
рейтинг книги
Геном хищника. Книга четвертая