gpt4 book ai didi

PHP fork 和多个子信号

转载 作者:可可西里 更新时间:2023-11-01 12:39:02 24 4
gpt4 key购买 nike

我正在尝试编写一个脚本,使用 pcntl_* functions 创建多个 fork 的子进程.

基本上,有一个脚本循环运行大约一分钟,定期轮询数据库以查看是否有要运行的任务。如果有的话,它应该在一个单独的进程中 fork 并运行该任务,这样父进程就不会被长时间运行的任务拖延。

由于可能有大量任务准备运行,我想限制创建的子进程的数量。因此,我通过在每次创建一个变量时递增一个变量(如果太多则暂停),然后在信号处理程序中递减它来跟踪进程数。有点像这样:

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 中的“匿名”解释了其原因。 :

Multiple children return less than the number of children exiting at a given moment SIGCHLD signals is normal behavior for Unix (POSIX) systems. SIGCHLD might be read as "one or more children changed status -- go examine your children and harvest their status values".

我的问题是:我如何检查子进程并获取它们的状态?是否有任何可靠的方法来检查在任何给定时间打开了多少子进程?

使用 PHP 5.2.9

最佳答案

一种方法是保留子进程的 PID 数组,并在信号处理程序中检查每个 PID 以查看它是否仍在运行。 (未经测试的)代码如下所示:

declare(ticks = 1);

$openProcesses = 0;
$procs = array();
$max = 3;

pcntl_signal(SIGCHLD, "childFinished");

while (!time_is_up()) {
if (there_is_something_to_do()) {
$pid = pcntl_fork();
if (!$pid) {
foo();
exit(0);
} else {

$procs[] = $pid; // add the PID to the list

++$openProcesses;
if ($openProcesses >= $max) {
pcntl_wait($status);
}
}
} else {
sleep(3);
}
}

function childFinished($signo) {

global $openProcesses, $procs;

// Check each process to see if it's still running
// If not, remove it and decrement the count
foreach ($procs as $key => $pid) if (posix_getpgid($pid) === false) {
unset($procs[$key]);
$openProcesses--;
}

}

关于PHP fork 和多个子信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2271108/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com