Sto provando a scrivere uno script che crea un numero di processi figlio biforcati utilizzando lo pcntl_*
functions.biforcazione PHP e segnali figlio multipli
Fondamentalmente, c'è un singolo script che viene eseguito in un ciclo per circa un minuto, periodicamente interrogando un database per vedere se c'è un compito da eseguire. Se ce n'è uno, dovrebbe forchetta ed eseguire l'attività in un processo separato in modo che il genitore non sia bloccato da un'attività di lunga durata.
Poiché potrebbe esserci un numero elevato di attività pronte per essere eseguite, desidero limitare il numero di processi figli creati. Pertanto, sto tenendo traccia del numero di processi incrementando una variabile ogni volta che ne viene creata una (e poi facendo una pausa se ce ne sono troppi), e quindi decrementandola in un gestore di segnale. Un po 'come questo:
define(ticks = 1);
$openProcesses = 0; // how many we have open
$max = 3; // the most we want open at a time
pcntl_signal(SIGCHLD, "childFinished");
while (!time_is_up()) {
if (there_is_something_to_do()) {
$pid = pcntl_fork();
if (!$pid) { // I am the child
foo(); // run the long-running task
exit(0); // and exit
} else { // I am the parent
++$openProcesses;
if ($openProcesses >= $max) {
pcntl_wait($status); // wait for any child to exit
} // before continuing
}
} else {
sleep(3);
}
}
function childFinished($signo) {
global $openProcesses;
--$openProcesses;
}
Questo funziona più o meno bene la maggior parte del tempo, tranne quando due o più processi terminano contemporaneamente - la funzione di gestore di segnale viene chiamato una sola volta, che tiri fuori il mio contatore. La ragione di questo si spiega con "Anonimo" nel notes of the PHP manual:
bambini più ritorno inferiore al numero dei bambini che escono in un dato segnali SIGCHLD momento è un comportamento normale per sistemi Unix (POSIX). SIGCHLD potrebbe essere letto come "uno o più bambini hanno cambiato lo stato - vai a esaminare i tuoi figli e raccogli i loro valori di stato".
La mia domanda è questa: Come esaminare i bambini e raccogliere il loro stato? Esiste un modo affidabile per verificare quanti processi figli sono aperti in un dato momento?
Utilizzo di PHP 5.2.9
probabilmente solo utilizzando https://www.rabbitmq.com/ renderebbe tutto molto meno soggetto a errori –