- Очередь сообщений linux posix
- Library interfaces and system calls
- Versions
- Kernel configuration
- Persistence
- Linking
- /proc interfaces
- Resource limit
- Mounting the message queue file system
- Polling message queue descriptors
- CONFORMING TO
- NOTES
- 7.3.4 Очереди сообщений POSIX
- Русские Блоги
- 05. очередь сообщений Posix
- 1 Обзор
- 2. Функции mq_open, mq_close и mq_unlink
- 2.1. Пример: программа mqcreate1
- 2.2 Пример: программа mqunlink
- 3. Функции mq_getattr и mq_setattr
- 3.1. Пример: программа mqgetattr
- 3.2 Пример: программа mqcreate
- 4. Функции mq_send и mq_receive
- 4.1. Пример: программа mqsend
- 4.2. Пример: программа mqreceive
- 5. Функция mq_notify
- 5.1. Пример: простое уведомление о сигнале
- 6. Резюме
Очередь сообщений linux posix
Message queues are created and opened using mq_open (3); this function returns a message queue descriptor ( mqd_t ), which is used to refer to the open message queue in later calls. Each message queue is identified by a name of the form /somename . Two processes can operate on the same queue by passing the same name to mq_open (3).
Messages are transferred to and from a queue using mq_send (3) and mq_receive (3). When a process has finished using the queue, it closes it using mq_close (3), and when the queue is no longer required, it can be deleted using mq_unlink (3). Queue attributes can be retrieved and (in some cases) modified using mq_getattr (3) and mq_setattr (3). A process can request asynchronous notification of the arrival of a message on a previously empty queue using mq_notify (3).
A message queue descriptor is a reference to an open message queue description (cf. open (2)). After a fork (2), a child inherits copies of its parent’s message queue descriptors, and these descriptors refer to the same open message queue descriptions as the corresponding descriptors in the parent. Corresponding descriptors in the two processes share the flags ( mq_flags ) that are associated with the open message queue description.
Each message has an associated priority , and messages are always delivered to the receiving process highest priority first. Message priorities range from 0 (low) to sysconf(_SC_MQ_PRIO_MAX) — 1 (high). On Linux, sysconf(_SC_MQ_PRIO_MAX) returns 32768, but POSIX.1-2001 only requires an implementation to support priorities in the range 0 to 31; some implementations only provide this range.
The remainder of this section describes some specific details of the Linux implementation of POSIX message queues.
Library interfaces and system calls
In most cases the mq_*() library interfaces listed above are implemented on top of underlying system calls of the same name. Deviations from this scheme are indicated in the following table:
Library interface | System call |
mq_close(3) | close(2) |
mq_getattr(3) | mq_getsetattr(2) |
mq_notify(3) | mq_notify(2) |
mq_open(3) | mq_open(2) |
mq_receive(3) | mq_timedreceive(2) |
mq_send(3) | mq_timedsend(2) |
mq_setattr(3) | mq_getsetattr(2) |
mq_timedreceive(3) | mq_timedreceive(2) |
mq_timedsend(3) | mq_timedsend(2) |
mq_unlink(3) | mq_unlink(2) |
Versions
Kernel configuration
Persistence
Linking
/proc interfaces
Resource limit
Mounting the message queue file system
After the file system has been mounted, the message queues on the system can be viewed and manipulated using the commands usually used for files (e.g., ls (1) and rm (1)).
The contents of each file in the directory consist of a single line containing information about the queue: These fields are as follows: QSIZE Number of bytes of data in all messages in the queue. NOTIFY_PID If this is non-zero, then the process with this PID has used mq_notify (3) to register for asynchronous message notification, and the remaining fields describe how notification occurs. NOTIFY Notification method: 0 is SIGEV_SIGNAL ; 1 is SIGEV_NONE ; and 2 is SIGEV_THREAD . SIGNO Signal number to be used for SIGEV_SIGNAL .
Polling message queue descriptors
CONFORMING TO
NOTES
Linux does not currently (2.6.26) support the use of access control lists (ACLs) for POSIX message queues.
Источник
7.3.4 Очереди сообщений POSIX
Очередь сообщений POSIX 1003.1b обеспечивает детерминированные и эффективные средства IPC. Она предлагает следующие преимущества для приложений реального времени:
▪ Буферы сообщений в очереди сообщений являются предварительно выделенными, обеспечивая доступность ресурсов, когда они необходимы.
▪ Сообщениям могут быть назначены приоритеты. Высокоприоритетные сообщения всегда принимаются первыми, независимо от количества сообщений в очереди.
▪ Она предлагает асинхронное уведомление при поступлении сообщения, если приёмник не хочет ожидать получения сообщения.
▪ Функции отправки и получения сообщений по умолчанию являются блокирующими вызовами. Приложения могут указать время ожидания при отправке или получении сообщений, чтобы избежать недетерминированной блокировки.
Интерфейсы перечислены в Таблице 7.5. Использование некоторых основных функций очереди сообщений иллюстрирует Распечатка 7.8. В этом примере создаются два процесса: один отправляет сообщение в очередь сообщений, а другой получает сообщение из очереди.
Таблица 7.5 Функции для работы с очередью сообщений POSIX.1b
Открытие/создание очереди сообщений.
Закрытие очереди сообщений.
Получение атрибутов очереди сообщений.
Установка атрибутов очереди сообщений.
Отправка сообщения в очередь.
Приём сообщения из очереди.
Отправка сообщения в очередь. Блокируется в течение заданного времени.
Приём сообщения из очереди. Блокируется в течение заданного времени.
Регистрация для получения уведомления всякий раз, когда получено сообщение в пустой очереди сообщений.
Удаление очереди сообщений.
Компиляция и запуск приведённых выше двух программ даёт следующий результат:
# gcc –o mqueue-1 mqueue-1.c –lrt
# gcc –o mqueue-2 mqueue-2.c –lrt
O_NONBLOCK not set
Message: Hello Posix World, prio = 1
Временем блокировки приложения для отправки или получения сообщений можно управлять с помощью функций mq_timedsend и mq_timedreceive . Если очередь сообщений заполнена и флаг O_NONBLOCK не установлен, функция mq_timedsend завершается за указанное время (это может произойти, если очередь заполнена и функция отправки блокируется, пока не получит свободный буфер). Точно так же mq_timedreceive завершается за указанное время, если в очереди нет сообщений. Использование функций mq_timedsend и mq_timedreceive иллюстрирует следующий фрагмент кода. Обе ожидают не более 10-ти секунд для отправки или получения сообщений.
struct timespec ts;
/* С этого момента указывает время ожидания как 10 с. */
ts.tv_sec = time(NULL) + 10;
if (mq_timedsend(ds, text, SIZE,PRIOTITY, &ts) == -1)<
if (errno == ETIMEDOUT)<
printf(«Timeout when waiting for message.»);
if (mq_timedreceive(ds, new_text, SIZE, &prio, &ts) == -1)<
if (errno == ETIMEDOUT)<
printf(«Timeout when waiting for message.»);
Асинхронный механизм для процессов для получения уведомления, что в очереди сообщений есть сообщения, вместо синхронной блокировки в mq_receive или mq_timedreceive , обеспечивает функция mq_notify . Этот интерфейс очень удобен для приложений реального времени. Процесс может вызвать функцию mq_notify , чтобы зарегистрироваться для асинхронных уведомлений, а затем может выполнять другую работу. Когда приходит сообщение, в очередь процессу направляется уведомление. После уведомления, для получения сообщения процесс может вызвать mq_receive . Прототип mq_notify :
int mq_notify(mqd_t mqdes,
const struct sigevent *notification);
Приложение может зарегистрироваться на два типа уведомлений:
▪ SIGEV_SIGNAL : отправить процессу сигнал, указанный в notification->sigev_signo , когда в очередь приходит сообщение. Использование иллюстрирует Распечатка 7.9.
▪ SIGEV_THREAD : вызвать при поступлении сообщения в очередь в отдельном потоке notification->sigev_notify_function . Использование иллюстрирует Распечатка 7.10.
Реализация в Linux
Подобно реализации в Linux совместно используемой памяти POSIX, Linux реализует очереди сообщений POSIX как файловую систему mqueue . Файловая система mqueue обеспечивает необходимую поддержку ядра для библиотеки пользовательского пространства, которая реализует интерфейсы очереди сообщений POSIX. По умолчанию ядро монтирует файловую систему внутренне и её не видно в пространстве пользователя. Тем не менее, вы можете смонтировать файловую систему mqueue .
# mount -t mqueue none /dev/mqueue
Эта команда монтирует файловую систему mqueue в /dev/mqueue . Очередь сообщений представлена в виде файла в /dev/mqueue . Но вы не можете отправить или получить сообщение из очереди «записывая» или «читая» из «файла» очереди сообщений. Чтение файла даёт размер очереди и уведомительную информацию, которая не доступна через стандартные процедуры. Удалите из Распечатки 7.8 mq_unlink , а затем скомпилируйте и запустите.
# gcc mqueue-1.c -lrt
QSIZE:17 NOTIFY:0 SIGNO:0 NOTIFY_PID:0
В выводе, показанном выше:
▪ QSIZE : размер очереди сообщений
▪ NOTIFY : либо 0, либо SIGEV_SIGNAL или SIGEV_THREAD
▪ SIGNAL : номер сигнала, используемого для уведомления
▪ NOTIFY_PID : PID процесса, ожидающего уведомление
Для регулировки количества ресурсов, используемых файловой системой, файловая система mqueue также предоставляет управление параметрами (sysctls) в каталоге /proc/sys/fs/mqueue . Этими параметрами являются:
▪ queues_max : чтение/запись этого файла позволяет получить/установить максимальное количество очередей сообщений, разрешённых в системе. Например, echo 128 > queues_max позволяет создание максимум 128 очередей сообщений в системе.
▪ msg_max : чтение/запись этого файла позволяет получить/установить максимальное количество сообщений в очереди.Максимальное количество сообщений, указанное при вызове mq_open , должно быть меньше или равно msg_max .
▪ msgsize_max : чтение/запись файла позволяет получить/установить максимальное значение размера сообщения. Оно является значением по умолчанию, если во время вызова mq_open максимальный размер сообщения не задан.
Что следует помнить
▪ Когда процесс получает из очереди сообщение, это сообщение удаляется из очереди.
▪ Если флаг O_NONBLOCK не указан, mq_send блокируется, пока в очереди не появится свободное место для добавления сообщения в очередь. Если, чтобы отправить сообщение, ждёт более чем один поток или процесс, и в очереди появляется свободное место, то для отправки сообщения разблокируется поток/процесс самого высокого приоритета, который ждал дольше всех. То же самое касается mq_receive .
▪ В любой момент времени только один процесс может быть зарегистрирован для получения уведомления от очереди сообщений. Если вызывающий процесс или любой другой процесс уже зарегистрирован для уведомления о прибытии сообщения, последующие попытки зарегистрироваться в очереди сообщений тем же или другим процессом окончатся неудачей.
▪ Для отмены существующей регистрации вызовите mq_notify с параметром «уведомление», равным NULL.
▪ После отправки уведомления зарегистрированному процессу его регистрация удаляется и очередь сообщений доступна для дальнейшей регистрации.
▪ Если какой-нибудь поток процесса заблокирован в mq_receive и этот процесс также зарегистрировал уведомление, прибывающее сообщение поступает в mq_receive и уведомление не посылается.
Источник
Русские Блоги
05. очередь сообщений Posix
1 Обзор
Очередь сообщений можно рассматривать как Список сообщений . Достаточно Разрешение на запись Темы могут ставить сообщения в очередь, достаточно Разрешение на чтение Поток может забрать сообщение из очереди. Каждое сообщение — это запись, которую присваивает отправитель. приоритет . Перед тем как процесс записывает сообщение в очередь, другому процессу не нужно ждать, пока сообщение поступит в очередь. Это противоположно каналам и FIFO. Для последних двух, если читатель еще не существует, нет смысла сначала иметь писателя.
Процесс может записать несколько сообщений в определенную очередь, а затем завершить работу и позволить другому обработать эти сообщения в какой-то момент в будущем. Мы сказали, что очередь сообщений При настойчивости ядра , Что отличается от каналов и FIFO. Когда происходит последнее закрытие канала или FIFO, данные, все еще находящиеся в канале или FIFO, будут отброшены.
Есть много общего между очередью сообщений Posix и очередью сообщений System V. Ниже приведены основные различия.
- Чтение очереди сообщений Posix всегда Вернуть самое старое сообщение с наивысшим приоритетом , Чтение очереди сообщений System V может вернуть Сообщения с произвольным приоритетом ;
- При помещении сообщения в пустую очередь очередь сообщений Posix позволяет генерировать сигнал или запускать поток, в то время как очередь сообщений System V не предоставляет аналогичный механизм.
Каждое сообщение в очереди имеет следующие атрибуты:
- Беззнаковый целочисленный приоритет (Posix) или длинный целочисленный тип (System V);
- Длина информационной части сообщения (может быть 0);
- Сами данные (если длина больше 0).
2. Функции mq_open, mq_close и mq_unlink
mq_open Функция создает новую очередь сообщений или открывает существующую очередь сообщений.
name: необходимо соблюдать правила именования IPC. Чтобы облегчить трансплантацию, он должен начинаться с символа косой черты и больше не может содержать никаких символов косой черты.
oflag: Параметр может быть одним из O_RDONLY, O_WRONLY или 0_RDWR, и может быть побитовым или O_CREAT, O_EXCL или O_NONBLOCK.
mq_close Закройте открытую очередь сообщений.
Его функция аналогична функции закрытия открытого файла: вызывающий процесс больше не может использовать дескриптор, но его очередь сообщений не может Не удалять из системы . Когда процесс завершается, все его открытые очереди сообщений закрываются, как и при вызове mq_close.
mq_unlink Удалите из системы имя, используемое в качестве первого параметра mq_open.
2.1. Пример: программа mqcreate1
Результаты:
После выполнения файл temp1.1234 не обнаружен. Сначала его нужно смонтировать, иначе созданный файл не удастся найти.
2.2 Пример: программа mqunlink
Программа mqunlink удаляет очередь сообщений из системы.
Результаты:
3. Функции mq_getattr и mq_setattr
Каждая очередь сообщений имеет четыре атрибута, mq_getattr возвращает все эти атрибуты, а mq_setattr устанавливает один из них.
Структура mq_attr содержит следующие атрибуты.
3.1. Пример: программа mqgetattr
Следующая программа используется для открытия указанной очереди сообщений и вывода ее свойств.
Результаты:
3.2 Пример: программа mqcreate
Позволяет указать максимальное количество сообщений в создаваемой очереди и максимальный размер каждого сообщения. Мы не можем указать только один из них без указания другого, то есть должны быть указаны оба.
Результаты:
4. Функции mq_send и mq_receive
Эти две функции используются соответственно для помещения сообщения в очередь и получения сообщения из очереди. Каждое сообщение имеет приоритет, который представляет собой целое число без знака меньше MQ_PRIO_MAX. Posix требует, чтобы этот верхний предел был не менее 32.
mq_receive всегда возвращается в указанную очередь Самое раннее сообщение с наивысшим приоритетом , И приоритет может быть возвращен с содержанием и длиной сообщения.
Первые три параметра этих двух функций аналогичны первым трем параметрам записи и чтения.
mq_receive Значение параметра len не может быть меньше максимального размера сообщения, которое может быть добавлено в указанную очередь (член mq_msgsize структуры mq_attr очереди). Если len меньше этого значения, mq_receive немедленно возвращает ошибку EMSGSIZE.
mq_send Параметр prio — это приоритет отправляемого сообщения, и его значение должно быть меньше MQ_PRIO_MAX. Если параметр priop в mq_receive является ненулевым указателем, приоритет возвращаемого сообщения сохраняется через этот указатель. Если приложению не нужно использовать сообщения с разными приоритетами, присвойте mq_send приоритет 0 и назначьте нулевой указатель на mq_receive в качестве последнего параметра.
4.1. Пример: программа mqsend
4.2. Пример: программа mqreceive
Результаты:
5. Функция mq_notify
Очередь сообщений Posix позволяет уведомлять об асинхронных событиях (уведомление об асинхронных событиях), когда сообщение помещается в пустую очередь сообщений. Выбрать это уведомление можно двумя способами:
- Генерировать сигнал;
- Создайте поток для выполнения указанной функции.
Это уведомление делается по телефону mq_notify настраивать.
Эта функция создает или удаляет асинхронные уведомления о событиях для указанной очереди. Эта структура и все новые константы, относящиеся к сигналам, представленные в этой главе, определены в заголовочном файле .
К этой функции обычно применяются несколько правил.
(1) Если параметр уведомления не пуст, то текущий процесс надеется получить уведомление, когда сообщение прибывает в указанную очередь, которая ранее была пустой. Мы говорим: «Процесс зарегистрирован для получения уведомлений из этой очереди».
(2) Если параметр уведомления является нулевым указателем, а текущий процесс в настоящее время зарегистрирован для получения уведомлений из указанной очереди, существующая регистрация будет отменена.
(3) Только один процесс может быть зарегистрирован для получения уведомлений из данной очереди в любое время.
(4) Когда сообщение поступает в очередь, которая ранее была пустой, и процесс был зарегистрирован для получения уведомлений из очереди, уведомление доступно только в том случае, если ни один поток не заблокирован в вызове mg_receive очереди Will выдаст. Это означает, что блокировка в вызове mg_reveive имеет приоритет над любой регистрацией уведомления.
(5) Когда уведомление отправляется в процесс регистрации, его регистрация аннулируется. Процесс должен снова вызвать mg_notify для повторной регистрации (при желании).
5.1. Пример: простое уведомление о сигнале
Окно A выполняет следующие команды:
Выполните следующую команду из окна B:
После того, как окно B выполнит команду, результат окна A будет следующим:
6. Резюме
Очередь сообщений Posix относительно проста: mq_open создать Новая очередь или открыть существующую очередь, mq_close закрыть Очередь, mq_unlink удалить Имя очереди. В очередь место Использование сообщения mq_send , Из очереди зачитать Использование сообщения mq_receive . Запрос и использование атрибутов очереди mq_getattr с участием mq_setattr , функция mq_notify Это позволяет нам зарегистрировать сигнал или поток, который отправляется (сигнал) или активируется (поток), когда сообщение помещается в пустую очередь.Каждому сообщению в очереди дается небольшой целочисленный приоритет. mq_receive При каждом вызове всегда возвращается самое старое сообщение с наивысшим приоритетом.
Источник