ИМЯ 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)
Устойчивость Очереди сообщений 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 по
Предел 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)) устанавливается автоматически на файловом сообщений 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).
СМОТРИТЕ ТАКЖЕ getrlimit(2), mq_getsetattr(2), poll(2), select(2), mq_close(3), mq_getattr(3), mq_notify(3), mq_open(3), mq_receive(3), mq_send(3), mq_unlink(3), epoll(7), namespaces(7)
|