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_*() реализуются поверх системных вызовов с теми же именами. Исключения из этого правила перечислены в следующей таблице:
Библиотечный интерфейс | Системный вызов |
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) |
Версии
Поддержка очередей сообщений 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 изменялось в разных версиях ядра следующим образом:
|
|||||||
/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 изменялся в разных версиях ядер следующим образом:
|
|||||||
Предел 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).