Domanda

Ho un arrangiamento genitore / lavoratore in corso. Il genitore mantiene i PID dei lavoratori in un array, costantemente controllando che sono ancora vivi con il seguente ciclo:

// $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);

Il problema è che è sempre pcntl_waitpid() impostazione $status a 0, quindi la prima volta questo ciclo viene eseguito, il genitore pensa che tutti i suoi figli sono usciti normalmente, anche se sono ancora in funzione. Sto usando pcntl_waitpid() in modo non corretto, o aspettavo di fare qualcosa che non?

È stato utile?

Soluzione

Semplice, il bambino non ha terminato o interrotta. Hai aggiunto la bandiera WNOHANG , così sarà sempre tornare subito ( racconta la funzione di non aspettare per un evento). Che cosa si dovrebbe fare è verificare il valore di ritorno di pcntl_waitpid per vedere se qualche cosa di valore è stato restituito (supponendo che si desidera solo per eseguire il contenuto del ciclo se c'è un cambiamento di stato):

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;
    }
}    

Altri suggerimenti

Sei davvero "usando pcntl_waitpid() sbagliato" (nota le virgolette)

Dal momento che si sta utilizzando WNOHANG, solo se pcntl_waitpid() ritorna PID del bambino, si può valutare che cosa è in $status.

valori di ritorno per pcntl_waitpid().

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top