[Хотя я работаю в Perl, я считаю, что этот вопрос относится к Linux System V IPC
API и ограничения, а не что-то специфичное для Perl.]
У меня есть две машины Centos, каждая с выпуском CentOS Linux 7.9.2009 (Core).
У меня есть программа, которая разветвляет дочерний элемент, а затем использует сообщения System V IPC для связи с дочерним элементом, дочерний элемент готовит ответы и отправляет их родителю.
На одной машине мы видим ожидаемое поведение. Ребенок создает пакеты сообщений, родитель их потребляет. Иногда дочерний процесс работает немного быстрее, чем родитель, и поэтому может заполнить очередь, затем дочерний элемент ждет, пока родитель не обработает некоторые сообщения, и продолжит работу.
Мы можем проверить размеры очереди с помощью ipcs -q и увидеть, что ограничение по умолчанию в 10 сообщений в очереди иногда достигается, дочерний процесс приостанавливается, а затем мы видим, что очередь пуста, как и ожидалось.
Мы считаем, что лимиты очередей указаны в файлах в /proc/sys/фс/mqueue/ и например msg_max считается ожидаемым 10.Эти значения идентичны на обеих машинах.
Мы также можем просмотреть пользовательские ulimits, относящиеся к очереди, используя улимит -q и видим значение, превышающее 800 000 байт на обеих машинах.
Загадка в том, что на нашей второй машине мы видим, как ребенок записывает в очередь три сообщения, пытается записать четвертое и ждет — мы намеренно не устанавливаем тайм-аут.
Как будто писатель считает, что очередь заполнена, хотя ipcs -q показывает только 3 элемента в очереди. На данный момент родитель еще не пытается читать сообщения.
------ Очереди сообщений --------
владелец ключа msqid разрешает использование сообщений в байтах
0x0000002a 1474560 дэйв 600 15020 3
Вопрос: что, кроме переполнения очереди, может привести к приостановке msgsnd()?
Пауза, кажется, продолжается бесконечно, ребенок продолжает, когда родитель
становится активным и читает некоторые сообщения.
У нас есть много машин, на которых работает этот код без проблем. Он не работает на трех новых машинах.
Предположительно, есть какая-то специфичная для среды функция, которая взаимодействует с нашим кодом?
Perl-код использует тонкую библиотеку над системными вызовами (подробности опущены).
$mQueue = msgget(IPC_PRIVATE, IPC_CREAT | S_IRUSR | S_IWUSR);
msgsnd($mQueue, pack("l! a*", length($msg), $msg);