Linux repositories inspector

mq_overview(7) - Russkiy

Linux
2017-09-15

man-pages-ru

Russian man pages from the Linux Documentation Project

manpages

Manual pages about using a GNU/Linux system

man-pages

Linux kernel and C library user-space interface documentation

ИМЯ

mq_overview - обзор очередей сообщений POSIX

ОПИСАНИЕ

Очереди сообщений POSIX позволяют процессам обмениваться данными в виде сообщений. Данный программный интерфейс отличается от используемого в очередях сообщений System V (msgget(2), msgsnd(2), msgrcv(2), etc.), но предоставляет схожие возможности.
Очереди сообщений создаются и открываются с помощью mq_open(3); эта функция возвращает дескриптор очереди сообщений (mqd_t), который используется в последующих вызовах для ссылки на открытую очередь сообщений. Каждая очередь сообщений описывается именем в виде /некое_имя; оно представляет собой строку с null в конце и длиной до NAME_MAX (т. е., 255) символов, состоящую из начальной косой черты, одного и более символа (любого, кроме косой черты). Два процесса могут работать через одну очередь, если укажут одинаковое имя в mq_open(3).
Сообщения передаются в и из очереди с помощью функций mq_send(3) и mq_receive(3). Когда процесс прекращает использовать очередь, он закрывает её с помощью функции mq_close(3), и если очередь больше не нужна, то она может быть удалена с помощью функции mq_unlink(3). Атрибуты очереди можно получить и (в некоторых случаях) изменить с помощью функций mq_getattr(3) и mq_setattr(3). Процесс может запросить асинхронное уведомление о поступлении сообщения в пустую очередь с помощью функции mq_notify(3).
Дескриптор очереди сообщений — это ссылка на открытое описание очереди сообщений (смотрите open(2)). После вызова fork(2) потомок наследует копии дескрипторов очередей сообщений родителя и эти дескрипторы ссылаются на те же открытые описания очередей сообщений родителя. Соответствующие дескрипторы очередей сообщений двух процессов используют общий флаг (mq_flags), который связан с открытым описанием очереди сообщений.
У каждого сообщения есть приоритет, и сначала в принимающий процесс всегда доставляются сообщения наивысшим приоритетом. Диапазон приоритетов сообщений: 0 (низший) — sysconf(_SC_MQ_PRIO_MAX) - 1 (высший). В Linux, sysconf(_SC_MQ_PRIO_MAX) возвращает 32768, но в POSIX.1 требуется реализация поддержки только диапазона приоритетов от 0 до 31; некоторые реализации предоставляют только этот диапазон.
Далее в разделе описываются особенности реализации очередей сообщений POSIX в Linux.

Библиотечные интерфейсы и системные вызовы

В большинстве случаев, перечисленные выше библиотечные интерфейсы mq_*() реализуются поверх системных вызовов с теми же именами. Исключения из этого правила перечислены в следующей таблице:

Версии

Поддержка очередей сообщений POSIX началась в ядре Linux версии 2.6.6. Поддержка в glibc предоставляется с версии 2.3.4.

Конфигурация ядра

Поддержка очередей сообщений POSIX включается параметром настройки ядра CONFIG_POSIX_MQUEUE. Данный параметр включён по умолчанию.

Устойчивость

Очереди сообщений POSIX располагаются в ядре. Пока очередь не удалёна с помощью mq_unlink(3), она остаётся в системе до её выключения.

Компоновка

Программы, в которых используется программный интерфейс очереди сообщений POSIX, для компоновки с библиотекой реального времени librt должны компилироваться с помощью cc -lrt.

Интерфейсы /proc

Для ограничения потребления очередями сообщений POSIX памяти ядра и задания атрибутов по умолчанию для новых очередей сообщений, можно использовать следующие интерфейсы:
/proc/sys/fs/mqueue/msg_default (начиная с Linux 3.5)
В данном файле задаётся значение, которое используется для mq_maxmsg в создаваемой новой очереди с помощью вызова mq_open(3) со значением attr равным NULL. Значение для этого файла по умолчанию равно 10. Минимальное и максимальные значение такие же как для /proc/sys/fs/mqueue/msg_max. Значение по умолчанию mq_maxmsg у новой очереди будет меньше msg_default и msg_max. До Linux 2.6.28 значение mq_maxmsg по умолчанию равнялось 10; с Linux 2.6.28 по Linux 3.4 значение по умолчанию равнялось ограничению msg_max.
/proc/sys/fs/mqueue/msg_max
Данный файл можно использовать для просмотра и изменения значения максимального количества сообщений в очереди. Это значение служит верхним пределом для аргумента attr->mq_maxmsg, указываемого в mq_open(3). Значение msg_max по умолчанию равно 10. Минимальное значение равно 1 (10 в ядрах до версии 2.6.28). Верхний предел равен HARD_MSGMAX. Ограничитель msg_max игнорируется для привилегированных процессов (CAP_SYS_RESOURCE), но, тем не менее, учитывается предел HARD_MSGMAX.
Определение HARD_MSGMAX изменялось в разных версиях ядра следующим образом:
* До Linux 2.6.32: 131072 / sizeof(void *)
* Linux 2.6.33 по 3.4: (32768 * sizeof(void *) / 4)
* Начиная с Linux 3.5: 65536
/proc/sys/fs/mqueue/msgsize_default (начиная с Linux 3.5)
В данном файле задаётся значение, которое используется для mq_msgsize в создаваемой новой очереди с помощью вызова mq_open(3) со значением attr равным NULL. Значение для этого файла по умолчанию равно 8192 (байты). Минимальное и максимальные значение такие же как для /proc/sys/fs/mqueue/msgsize_max. Если msgsize_default превышает msgsize_max, то значение mq_msgsize для новой очереди по умолчанию ограничивается msgsize_max.До Linux 2.6.28 значение mq_msgsize по умолчанию равнялось 8192; с Linux 2.6.28 по Linux 3.4 значение по умолчанию равнялось ограничению msgsize_max.
/proc/sys/fs/mqueue/msgsize_max
Данный файл можно использовать для просмотра и изменения максимального размера сообщения. Это значение служит верхним пределом для аргумента attr->mq_msgsize, указываемого в mq_open(3). Значение msgsize_max по умолчанию равно 8192 байта. Минимальное значение равно 128 (8192 в ядрах до версии 2.6.28). Верхний предел msgsize_max изменялся в разных версиях ядер следующим образом:
* До Linux 2.6.28 верхний предел был равен INT_MAX.
* С Linux 2.6.28 по 3.4 предел равен 1048576.
* Начиная с Linux 3.5 предел равен 16777216 (HARD_MSGSIZEMAX).
Предел msgsize_max игнорируется для привилегированных процессов (CAP_SYS_RESOURCE), но, начиная с Linux 3.5, накладывается ограничение HARD_MSGSIZEMAX.
/proc/sys/fs/mqueue/queues_max
Данный файл можно использовать для просмотра и изменения системного ограничения на количество сообщений в очереди. Значение queues_max по умолчанию равно 256. У queues_max нет верхнего предела; привилегированные процессы (CAP_SYS_RESOURCE) могут превышать ограничение (но смотрите ДЕФЕКТЫ).

Ограничение ресурса

Ограничение ресурса RLIMIT_MSGQUEUE, накладываемое на количество пространства, которое могут занять все очереди сообщений, принадлежащие процессу с реальным пользовательским ID, описано в getrlimit(2).

Монтирование файловой системы очереди сообщений

В Linux очереди сообщений создаются в виртуальной файловой системе (другие реализации могут делать также, но, вероятно, по-другому). Данная файловая система может быть смонтирована (суперпользователем) с помощью команд:
# mkdir /dev/mqueue # mount -t mqueue none /dev/mqueue
Закрепляющий бит устанавливается на каталог назначения автоматически.
После примонтирования файловой системы очередь сообщений в системе можно просматривать и изменять с помощью команд как с обычными файлами (например, ls(1) и rm(1)).
Содержимое каждого файла в каталоге состоит из одной строки, в которой представлена информация об очереди:
$ cat /dev/mqueue/mymq QSIZE:129 NOTIFY:2 SIGNO:0 NOTIFY_PID:8260
Эти поля означают следующее:
QSIZE Количество байтов данных во всех сообщениях очереди (но смотрите ДЕФЕКТЫ).
NOTIFY_PID
Если это значение не равно нулю, то процесс с данным PID использовал mq_notify(3) для регистрации асинхронных уведомлений о сообщениях, а оставшиеся поля описывают как производится уведомление.
NOTIFY Способ уведомления: 0 — SIGEV_SIGNAL; 1 — SIGEV_NONE; 2 — SIGEV_THREAD.
SIGNO Номер сигнала, который будет использован для SIGEV_SIGNAL.

Реализация дескрипторов очереди сообщений в Linux

В Linux дескриптор очереди сообщений представляет собой файловый дескриптор (в POSIX не требуется этого от реализации). Это означает, что за дескриптором очереди сообщений можно следить с помощью select(2), poll(2) или epoll(7). Это является непереносимым свойством.
Флаг close-on-exec (смотрите open(2)) устанавливается автоматически на файловом дескрипторе, возвращаемом mq_open(2).

Пространства имён IPC

Обсуждение связи объектов очереди сообщений POSIX с пространствами IPC смотрите в ipc_namespaces(7).

ЗАМЕЧАНИЯ

Очереди сообщений System V (msgget(2), msgsnd(2), msgrcv(2) и т. д.) — более старый программный интерфейс обмена сообщениями между процессами. Очереди сообщений POSIX имеют более проработанный интерфейс чем очереди сообщений System V; с другой стороны, очереди сообщений POSIX не так широко распространены (особенно в старых системах) чем очереди сообщений System V.
В Linux (версия 2.6.26) пока нет поддержки использования списков контроля доступа (ACL) для очередей сообщений POSIX.

ДЕФЕКТЫ

В Linux версиях с 3.5 по 3.14 ядро устанавливает верхний предел в 1024 (HARD_QUEUESMAX) на значение ограничения queues_max и это влияет даже на привилегированные процессы. Это предельное значение было удалено в Linux 3.14, а также есть заплаты к стабильным ядрам версий с 3.5.x по 3.13.x для удаления этого предела.
Первоначально реализованное (и описанное) поле QSIZE показывало общее количество (пользовательских) байт всех сообщений в очереди. Некоторые изменения в Linux 3.5 непреднамеренно изменили это поведение, и поле стало также включать байты издержек ядра, которые требуются для хранения сообщений в очереди. Это было исправлено в Linux 4.2 (и более ранних стабильных ядрах), и теперь снова считаются байты только пользовательских сообщений в очереди.

ПРИМЕР

Пример использования функций работы с очередью сообщений смотрите в mq_notify(3).
⇧ Top