Próbuję napisać skrypt, który tworzy liczbę rozwidlonych procesów potomnych za pomocą pcntl_*
functions.Rozwidlenia PHP i wiele sygnałów potomnych
Zasadniczo istnieje pojedynczy skrypt, który działa w pętli przez około minutę, okresowo odpytywanie bazy danych, aby sprawdzić, czy istnieje zadanie do uruchomienia. Jeśli takowy istnieje, powinien rozwidlić i uruchomić zadanie w oddzielnym procesie, aby rodzic nie był zatrzymany przez długo działające zadanie.
Ponieważ prawdopodobnie istnieje duża liczba zadań gotowych do uruchomienia, chcę ograniczyć liczbę tworzonych procesów podrzędnych. Dlatego śledzę liczbę procesów poprzez inkrementowanie zmiennej za każdym razem, gdy jest tworzony (a następnie wstrzymywanie, jeśli jest za dużo), a następnie zmniejszanie jej w procedurze obsługi sygnału. Niby tak:
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;
}
Działa to dość dużo ok większość czasu, z wyjątkiem, gdy dwa lub więcej procesów zakończyć jednocześnie - funkcja obsługi sygnału jest wywoływana tylko raz, co wyrzuca mój licznik. Powodem tego jest wyjaśnione przez „anonimowy” w notes of the PHP manual:
Wiele dzieci powrócić mniej niż liczba dzieci opuszczających w danej chwili jest sygnał SIGCHLD normalne zachowanie dla Unix (POSIX) systemów. SIGCHLD można odczytać jako "jeden lub więcej dzieci zmieniono status - idź zbadać swoje dzieci i zebrać ich wartości statusu".
Moje pytanie brzmi: Jak mogę sprawdzić dzieci i zebrać ich status? Czy istnieje jakiś niezawodny sposób sprawdzenia, ile procesów podrzędnych jest otwartych w danym momencie?
Używanie PHP 5.2.9
prawdopodobnie po prostu za pomocą https://www.rabbitmq.com/ sprawiłoby, że cała rzecz była znacznie mniej podatna na błędy –