Ограничения очереди сообщений Centos System V IPC

[Хотя я работаю в Perl, я считаю, что этот вопрос относится к API-интерфейсам и ограничениям IPC Linux System V, а не к чему-то, специфичному для Perl.]

У меня есть две машины Centos, каждая с CentOS Linux версии 7.9.2009 (Core).

У меня есть программа, которая разветвляет дочерний элемент, а затем использует сообщения System V IPC для связи с дочерним элементом, дочерний элемент готовит ответы и отправляет их родителю.

На одной машине мы видим ожидаемое поведение. Дочерний элемент создает пакеты сообщений, родительский их потребляет. Иногда дочерний элемент работает немного быстрее, чем родительский, и поэтому может заполнить очередь, затем дочерний элемент ждет, пока родительский элемент не получит несколько сообщений и продолжит работу.

Мы можем проверить размеры очередей с помощью ipcs -q и увидеть, что лимит по умолчанию в 10 сообщений в очереди иногда достигается, дочерний процесс приостанавливается, а затем мы видим, что очередь пуста, как и ожидалось.

Мы считаем, что ограничения очереди указаны в файлах /proc/sys/fs/mqueue/ и, например, msg_max равен ожидаемому значению 10. Эти значения идентичны на обеих машинах.

Мы также можем просмотреть пользовательские ограничения, относящиеся к очереди, с помощью ulimit -q и увидеть значение, превышающее 800000 байт на обеих машинах.

Загадка в том, что на нашей второй машине мы видим, как ребенок записывает в очередь три сообщения, пытается написать четвертое и ждет — мы намеренно не установили таймаут. Это как если бы автор записи считал, что очередь заполнена, хотя ipcs -q показывает в очереди только 3 элемента. На данный момент родитель еще не пытается прочитать сообщения.

      ------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    
0x0000002a 1474560    dave      600        15020        3  

Вопрос: что, кроме переполнения очереди, может привести к приостановке msgsnd()? Пауза, кажется, продолжается бесконечно, ребенок продолжает, когда родитель становится активным и читает какие-то сообщения.

У нас есть много машин, на которых этот код работает без проблем. На трех новых машинах он не работает. Предположительно, существует какая-то специфичная для среды функция, которая взаимодействует с нашим кодом?

Код Perl использует тонкую библиотеку над системными вызовами (подробности опущены).

      $mQueue = msgget(IPC_PRIVATE, IPC_CREAT | S_IRUSR | S_IWUSR);
msgsnd( $mQueue, pack("l! a*", length($msg), $msg);

1 ответ

Проблема заключалась в том, что максимальный размер очереди по умолчанию был установлен на низкое значение.

Эту калибровку можно просмотреть с помощью опции -l для ipcs.

      ipcs -q -l

------ Messages Limits --------
max queues system wide = 3671
max size of message (bytes) = 8192
default max size of queue (bytes) = 16384

Соответствующая настройка ядра хранится в

      /proc/sys/kernel/msgmnb

и может быть изменен (как root) с помощью команды

       sysctl -w kernel.msgmnb=65536
 kernel.msgmnb = 65536
Другие вопросы по тегам