Как я могу использовать статус $, возвращаемый pcntl_waitpid ()?

StackOverflow https://stackoverflow.com/questions/4586148

  •  14-10-2019
  •  | 
  •  

Вопрос

У меня есть договоренность родителей/работника. Родитель держит пиды работника в массиве, постоянно проверяя, что они все еще живы со следующей петлей:

// $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() Неправильно, или ожидая, что это сделает что -то, чего нет?

Это было полезно?

Решение

Просто, ребенок не вышел и не остановился. Вы добавили 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;
    }
}    

Другие советы

Вы действительно "используете pcntl_waitpid() неправильно »(обратите внимание на цитаты)

Поскольку вы используете WNOHANG, Только если pcntl_waitpid() Возвращает пид ребенка, вы можете оценить, что в $status.

Видеть возвращаемые значения за pcntl_waitpid().

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top