我想寫一個腳本,它使用pcntl_*
functions創建了一些分叉的子進程。PHP分叉和多個子信號
基本上,有一個腳本運行在大約一分鐘的循環中,定期輪詢數據庫以查看是否有要運行的任務。如果有一個,它應該在一個單獨的進程中分叉並運行該任務,以便該父項不被長時間運行的任務阻擋。
由於可能有大量的任務可以運行,我想限制創建的子進程的數量。因此,我通過在每次創建一個變量時增加一個變量來跟蹤進程的數量(然後在太多時暫停),然後在信號處理程序中對其進行遞減。有點像這樣:
define(ticks = 1);
$openProcesses = 0; // how many we have open
$max = 3; // the most we want open at a time
pcntl_signal(SIGCHLD, "childFinished");
while (!time_is_up()) {
if (there_is_something_to_do()) {
$pid = pcntl_fork();
if (!$pid) { // I am the child
foo(); // run the long-running task
exit(0); // and exit
} else { // I am the parent
++$openProcesses;
if ($openProcesses >= $max) {
pcntl_wait($status); // wait for any child to exit
} // before continuing
}
} else {
sleep(3);
}
}
function childFinished($signo) {
global $openProcesses;
--$openProcesses;
}
這工作非常OK的大部分時間,除了當兩個或多個進程同時完成 - 信號處理函數只被調用一次,它拋出我的櫃檯。這樣做的原因是「無名氏」在notes of the PHP manual解釋說:
多兒童重返不到孩子在某個特定時刻SIGCHLD信號退出的數量爲Unix(POSIX)系統的正常行爲。 SIGCHLD可能被解讀爲「一個或多個孩子改變了狀態 - 去檢查你的孩子並收穫他們的狀態值」。
我的問題是這樣的:我如何檢查孩子並獲得他們的狀態?是否有任何可靠的方法來檢查在任何給定時間打開了多少個子進程?
使用PHP 5.2.9
可能只是使用https://www.rabbitmq.com/會使整件事更不容易出錯 –