【发布时间】:2011-01-17 06:50:59
【问题描述】:
我正在尝试编写一个使用pcntl_* functions 创建多个分叉子进程的脚本。
基本上,有一个脚本循环运行大约一分钟,定期轮询数据库以查看是否有要运行的任务。如果有的话,它应该在一个单独的进程中派生和运行任务,这样父进程就不会被长时间运行的任务拖住。
由于可能有大量任务准备运行,我想限制创建的子进程的数量。因此,我通过在每次创建一个变量时增加一个变量来跟踪进程的数量(如果有太多则暂停),然后在信号处理程序中减少它。有点像这样:
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;
}
这在大多数情况下都可以正常工作,除非两个或多个进程同时完成 - 信号处理函数只调用一次,这会抛出我的计数器。原因由notes of the PHP manual中的“匿名”解释:
返回的多个子节点少于在给定时刻退出的子节点数量 SIGCHLD 信号是 Unix (POSIX) 系统的正常行为。 SIGCHLD 可能被解读为“一个或多个孩子改变了状态——去检查你的孩子并收获他们的状态值”。
我的问题是:我如何检查子进程并获取他们的状态?有没有可靠的方法来检查在任何给定时间打开了多少子进程?
使用 PHP 5.2.9
【问题讨论】:
-
可能只使用rabbitmq.com 会使整个事情更不容易出错