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?

Était-ce utile?

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().

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top