IPC msgsnd 意外等待
IPC msgsnd waits unexpectedly
[虽然我在 perl 工作,但我相信这个问题与 Linux System V IPC 有关
API 和限制而不是任何东西 perl-specific.]
我有两台 Centos 机器,每台都是 CentOS Linux 7.9.2009 版(核心)。
我有一个程序分叉 child,然后使用 System V IPC 消息与 child 通信,child 准备答案并将它们发送到 parent.
在一台机器上,我们看到了预期的行为。 child 生成消息批次,parent 消耗它们。有时 child 的工作速度比 parent 快一点,因此可能会填满队列,child 然后等待 parent 消耗一些消息并继续。
我们可以使用 ipcs -q 检查队列大小,发现偶尔会达到每个队列 10 条消息的默认限制,child 暂停,然后我们看到队列如预期的那样为空。
我们认为队列限制在 /proc/sys/fs/mqueue/ 中的文件中指定,例如 msg_max被认为是预期的 10。这些值在两台机器上是相同的。
我们还可以使用 ulimit -q 查看与队列相关的用户 ulimits,并在两台机器上看到超过 800,000 字节的值。
令人困惑的是,在我们的第二台机器上,我们看到 child 将三条消息写入队列并尝试写入第四条消息并等待 - 我们故意不设置超时。
就好像作者认为队列已满,即使 ipcs -q 显示队列中只有 3 个项目。此时 parent 尚未尝试读取消息。
------ Message Queues --------
key msqid owner perms used-bytes messages
0x0000002a 1474560 dave 600 15020 3
问题:除了队列已满,还有什么会导致 msgsnd() 暂停?
暂停似乎无限期地继续,child 在 parent 时继续
变得活跃并阅读一些消息。
我们有很多机器运行这段代码没有问题。它在三台新机器上失败。
大概有一些 environment-specific 功能与我们的代码交互?
perl 代码在系统调用之上使用了一个精简库(省略了详细信息)
$mQueue = msgget(IPC_PRIVATE, IPC_CREAT | S_IRUSR | S_IWUSR);
msgsnd( $mQueue, pack("l! a*", length($msg), $msg);
问题是队列的默认最大大小 内核设置设置为较低的值。
可以使用 ipcs 的 -l 选项查看此校准。
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
[虽然我在 perl 工作,但我相信这个问题与 Linux System V IPC 有关 API 和限制而不是任何东西 perl-specific.]
我有两台 Centos 机器,每台都是 CentOS Linux 7.9.2009 版(核心)。
我有一个程序分叉 child,然后使用 System V IPC 消息与 child 通信,child 准备答案并将它们发送到 parent.
在一台机器上,我们看到了预期的行为。 child 生成消息批次,parent 消耗它们。有时 child 的工作速度比 parent 快一点,因此可能会填满队列,child 然后等待 parent 消耗一些消息并继续。
我们可以使用 ipcs -q 检查队列大小,发现偶尔会达到每个队列 10 条消息的默认限制,child 暂停,然后我们看到队列如预期的那样为空。
我们认为队列限制在 /proc/sys/fs/mqueue/ 中的文件中指定,例如 msg_max被认为是预期的 10。这些值在两台机器上是相同的。
我们还可以使用 ulimit -q 查看与队列相关的用户 ulimits,并在两台机器上看到超过 800,000 字节的值。
令人困惑的是,在我们的第二台机器上,我们看到 child 将三条消息写入队列并尝试写入第四条消息并等待 - 我们故意不设置超时。 就好像作者认为队列已满,即使 ipcs -q 显示队列中只有 3 个项目。此时 parent 尚未尝试读取消息。
------ Message Queues --------
key msqid owner perms used-bytes messages
0x0000002a 1474560 dave 600 15020 3
问题:除了队列已满,还有什么会导致 msgsnd() 暂停? 暂停似乎无限期地继续,child 在 parent 时继续 变得活跃并阅读一些消息。
我们有很多机器运行这段代码没有问题。它在三台新机器上失败。 大概有一些 environment-specific 功能与我们的代码交互?
perl 代码在系统调用之上使用了一个精简库(省略了详细信息)
$mQueue = msgget(IPC_PRIVATE, IPC_CREAT | S_IRUSR | S_IWUSR);
msgsnd( $mQueue, pack("l! a*", length($msg), $msg);
问题是队列的默认最大大小 内核设置设置为较低的值。
可以使用 ipcs 的 -l 选项查看此校准。
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