[雖然我在 perl 作業,但我相信這個問題與 Linux System V IPC API 和限制有關,而不是任何特定于 perl 的東西。]
我有兩臺 CentOS 機器,每臺機器都是 CentOS Linux 7.9.2009(核心)。
我有一個程式可以分叉一個孩子,然后使用 System V IPC 訊息與孩子進行通信,孩子準備答案并將它們發送給父母。
在一臺機器上,我們看到了預期的行為。子行程產生成批的訊息,父行程消費它們。有時子行程比父行程運行得快一點,因此可能會填滿佇列,然后子行程等待父行程消耗一些訊息并繼續。
我們可以使用 ipcs -q 檢查佇列大小,看到每個佇列 10 條訊息的默認限制偶爾會達到,子行程暫停,然后我們看到佇列如預期的那樣空。
我們認為佇列限制在/proc/sys/fs/mqueue/中的檔案中指定,例如msg_max被視為預期的 10。這些值在兩臺機器上是相同的。
我們還可以使用ulimit -q查看與佇列相關的用戶ulimit,并在兩臺機器上看到超過 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);
uj5u.com熱心網友回復:
問題是佇列內核設定的默認最大大小設定為較低值。
可以使用 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
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/349239.html
下一篇:了解Perl包命名空間
