Читать книгу 📗 "Основы программирования в Linux - Мэтью Нейл"
Очереди сообщений предоставляют очень легкий и эффективный способ передачи данных между двумя несвязанными процессами. У них есть преимущество по сравнению с именованными каналами, заключающееся в том, что очередь сообщений существует независимо как от отправляющего, так и от принимающего процессов, что устраняет некоторые трудности, возникающие при синхронизации открытия и закрытия именованных каналов.
Очереди сообщений обеспечивают отправку блока данных из одного процесса в другой. Кроме того, каждый блок данных наделяется типом, и принимающий процесс может получать независимо блоки данных, имеющие разные типы. Хорошо и то, что, отправляя сообщения, вы можете почти полностью избежать проблем синхронизации и блокировки, связанных с именованными каналами. Еще лучше то, что вы можете проявить предусмотрительность в отношении неотложных в том или ином смысле сообщений. К недостаткам следует отнести то, что, как и в случае каналов, в системе существует ограничение максимального объема блока данных и максимального объема всех блоков данных во всех очередях.
Наложив эти ограничения, стандарт X/Open не позаботился о способе выяснения их числовых значений за исключением того, что превышение ограничений — достаточное основание для аварийного завершения функций обработки очереди сообщений. В ОС Linux есть два определения:
MSGMAXMSGMNBДалее приведены объявления функций для работы с очередями сообщений:
<b>#include <sys/msg.h></b><b>int msgctl(int msqid, int cmd, struct msqid_ds *buf);</b><b>int msgget(key_t key, int msgflg);</b><b>int msgrcv(int msqid, void *msg_ptr, size_t msg_sz, long int msgtype, int msgflg);</b><b>int msgsnd(int msqid, const void *msg_ptr, size_t msg_sz, int msgflg);</b>Как и в случае семафоров или совместно используемой памяти, заголовочные файлы sys/types.h и sys/ipc.h обычно автоматически включаются заголовочным файлом msg.h.
msgget
Очередь сообщений создается и предоставляет к себе доступ с помощью функции
msgget<b>int msgget(key_t key, int msgflg);</b>Программа должна предоставить значение параметра
keyIPC_PRIVATEmsgflgIPC_CREATORIPC_CREATIPC_CREATФункция
msggetmsgsnd
Функция
msgsnd<b>int msgsnd(int msqid, const void *msg_ptr, size_t msg_sz, int msgflg);</b>
Структура сообщения ограничена двумя способами. Во-первых, она должна быть меньше системного ограничения, и во-вторых, она должна начинаться с элемента типа
long int<b>struct my_message {</b><b> long int message_type;</b><b> /* Данные, которые вы собираетесь передавать */</b><b>}</b>Поскольку элемент
message_typeПервый параметр
msqidmsggetВторой параметр
msg_ptrlong intТретий параметр
msg_szmsg_ptrlong intЧетвертый параметр
msgflgmsgflgIPC_NOWAITmsgflgIPC_NOWAITВ случае успеха функция вернет 0, а в случае аварийного завершения — -1. Если вызов был успешен, копия данных сообщения принимается и помещается в очередь сообщений.
msgrcv
Функция
msgrcv<b>int msgrcv(int msqid, void *msg_ptr, size_t msg_sz, long int msgtype, int msgflg);</b>Первый параметр
msqidВторой параметр
msg_ptrlong intmsgsndТретий параметр
msg_szmsg_ptrlong intЧетвертый параметр
msgtypelong intmsgtypemsgtype