Comment puis-je utiliser le statut $ retourné par pcntl_waitpid ()?
-
14-10-2019 - |
Question
J'ai un arrangement parent / travailleur en cours. Le parent conserve les PIDs travailleurs dans un tableau, constamment vérifier qu'ils sont encore en vie avec la boucle suivante:
// $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);
Le problème est que pcntl_waitpid()
définit sans cesse $status
à 0, donc la première fois cette boucle est exécutée, le parent pense que tous ses enfants ont quitté normalement, même si elles sont encore en cours d'exécution. Suis-je utiliser pcntl_waitpid()
mal, ou d'attendre à faire quelque chose qu'il ne fonctionne pas?
La solution
simple, l'enfant n'a pas quitté ou arrêté. Vous avez ajouté le WNOHANG
drapeau, il retournera toujours immédiatement ( il indique à la fonction de ne pas attendre un événement). Ce que vous devez faire est de vérifier la valeur de retour de pcntl_waitpid
pour voir si quelque chose de valeur a été retourné (en supposant que vous voulez seulement exécuter le contenu de la boucle s'il y a un changement d'état):
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;
}
}
Autres conseils
Vous êtes en effet "à l'aide de faux pcntl_waitpid()
" (notez les guillemets)
Puisque vous utilisez WNOHANG
, uniquement si pcntl_waitpid()
retourne PID de l'enfant, vous pouvez évaluer ce qui est dans $status
.
Voir valeurs de retour pour pcntl_waitpid()
.