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

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

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

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

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

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

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

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

Загадка заключается в том, что на нашей второй машине мы видим, как ребенок записывает три сообщения в очередь и пытается записать четвертое и ждать — мы намеренно не устанавливаем тайм-аут. Как будто писатель считает, что очередь заполнена, хотя 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);
2
задан 1 November 2021 в 15:32
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
2
ответ дан 2 November 2021 в 04:29

Теги

Похожие вопросы