Как я могу использовать статус $, возвращаемый pcntl_waitpid ()?
-
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()
.