MQ_OVERVIEW(7) | Руководство программиста Linux | MQ_OVERVIEW(7) |
ИМЯ¶
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¶
For a discussion of the interaction of System V IPC objects and IPC namespaces, see 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).
СМ. ТАКЖЕ¶
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)
ЗАМЕЧАНИЯ¶
Эта страница является частью проекта Linux man-pages версии 4.16. Описание проекта, информацию об ошибках и последнюю версию этой страницы можно найти по адресу https://www.kernel.org/doc/man-pages/.
ПЕРЕВОД¶
Русский перевод этой страницы руководства был сделан aereiae <aereiae@gmail.com>, Alexey <a.chepugov@gmail.com>, Azamat Hackimov <azamat.hackimov@gmail.com>, Dmitriy S. Seregin <dseregin@59.ru>, Dmitry Bolkhovskikh <d20052005@yandex.ru>, ITriskTI <ITriskTI@gmail.com>, Max Is <ismax799@gmail.com>, Yuri Kozlov <yuray@komyakino.ru>, Иван Павлов <pavia00@gmail.com> и Малянов Евгений Викторович <maljanow@outlook.com>
Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3 или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.
Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на man-pages-ru-talks@lists.sourceforge.net.
15 сентября 2017 г. | Linux |