我有父母/工人的安排。父级将工作者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()
,或者期望它做一些它不会做的事情?
答案 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。