开发者

How do I use $status returned by pcntl_waitpid()?

开发者 https://www.devze.com 2023-02-02 00:23 出处:网络
I have a parent/worker arrangement going on.The parent keeps the worker PIDs in an array, constantly checking that they are still alive with the following loop:

I have a parent/worker arrangement going on. The parent keeps the worker PIDs in an array, constantly checking that they are still alive with the following loop:

// $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);

The problem is that pcntl_waitpid() is always setting 开发者_JAVA百科$status to 0, so the very first time this loop is run, the parent thinks that all of its children have exited normally, even though they are still running. Am I using pcntl_waitpid() incorrectly, or expecting it to do something that it doesn't?


Simple, the child has not exited or stopped. You added the WNOHANG flag, so it will always return immediately (It tells the function not to wait for an event). What you should do is check the return value of pcntl_waitpid to see if anything of value was returned (assuming that you only want to run the contents of the loop if there's a status change):

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;
    }
}    


You're indeed "using pcntl_waitpid() wrong" (Note the quotes)

Since you're using WNOHANG, only if pcntl_waitpid() returns the child's PID, you may evaluate what's in $status.

See return values for pcntl_waitpid().

0

精彩评论

暂无评论...
验证码 换一张
取 消