我如何使用pcntl_waitpid()返回的$ status?

时间:2011-01-03 16:19:10

标签: php parallel-processing pcntl

我有父母/工人的安排。父级将工作者PID保存在一个数组中,通过以下循环不断检查它们是否仍然存在:

// $workers is an array of PIDs
foreach ($workers as $workerID => $pid) {
    // Check if this worker still exists as a process
    pcntl_waitpid($pid, $status, WNOHANG|WUNTRACED);

    // If the worker exited normally, stop tracking it
    if (pcntl_wifexited($status)) {
        $logger->info("Worker $workerID exited normally");
        array_splice($workers, $workerID, 1); 
    }

    // If it has a session ID, then it's still living
    if (posix_getsid($pid))⋅
        $living[] = $pid;
}

// $dead is the difference between workers we've started
// and those that are still running
$dead = array_diff($workers, $living);

问题是pcntl_waitpid()始终将$status设置为0,因此第一次运行此循环时,父级认为其所有子级都已正常退出,即使它们仍然存在运行。我是否错误地使用pcntl_waitpid(),或者期望它做一些它不会做的事情?

2 个答案:

答案 0 :(得分:3)

简单,孩子没有退出或停止。您添加了WNOHANG标志,因此它将始终立即返回(它告诉函数不要等待事件)。你应该做的是检查pcntl_waitpid的返回值,看看是否返回了任何值(假设你只想在状态发生变化时运行循环的内容):

foreach ($workers as $workerID => $pid) {
    // Check if this worker still exists as a process
    if (pcntl_waitpid($pid, $status, WNOHANG|WUNTRACED)) {
        // If the worker exited normally, stop tracking it
        if (pcntl_wifexited($status)) {
            $logger->info("Worker $workerID exited normally");
            array_splice($workers, $workerID, 1); 
        }
        // If it has a session ID, then it's still living
        if (posix_getsid($pid))⋅
            $living[] = $pid;
    }
}    

答案 1 :(得分:2)

你确实“使用pcntl_waitpid()错误”(注意引号)

由于您使用的是WNOHANG,如果pcntl_waitpid()返回子级的PID,您可以评估$status中的内容。

pcntl_waitpid()return values