我想写一个脚本,它使用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/会使整件事更不容易出错 –