The code before isnt working for me cause the children are correctly started but not refreshed after they died. So keep in mind to use this instead and use the signal handler to know when a child exits to know when you have to start a new one. I added a few lines to the posting from {andy at cbeyond dot net} cause his post wasnt working for me as well (PHP5.1). Same effect like the one below.
<?php
declare(ticks = 1);
$max=5;
$child=0;
// function for signal handler
function sig_handler($signo) {
global $child;
switch ($signo) {
case SIGCHLD:
echo "SIGCHLD received\n";
$child--;
}
}
// install signal handler for dead kids
pcntl_signal(SIGCHLD, "sig_handler");
while (1){
$child++;
$pid=pcntl_fork();
if ($pid == -1) {
die("could not fork");
} else if ($pid) {
// we are the parent
if ( $child >= $max ){
pcntl_wait($status);
$child++;
}
} else {
// we are the child
echo "\t Starting new child | now we de have $child child processes\n";
// presumably doing something interesting
sleep(rand(3,5));
exit;
}
}
?>
pcntl_wait
(PHP 5)
pcntl_wait — Wartet auf ein oder gibt den Status eines abgezweigten Kindes zurück
Beschreibung
Die Funktion unterbricht die Ausführung des aktuellen Prozesses bis ein Kind sich beendet hat oder bis ein Signal ausgeliefert wurde dessen Aktion den aktuellen Prozess beendet oder eine Signalverabeitungsfunktion aufruft. Wenn ein Kind sich zum Zeitpunkt des Funktionsaufrufes bereits beendet hat (ein sog. "Zombie" Prozess) kehrt die Funktion umgehend zurück. Alle durch das Kind verwendeten Ressourcen werden freigegeben. Bitte schlagen Sie in der waitpid(2) man Seite Ihres Systems für spezifische Dateils nach, wie waitpid auf Ihrem System arbeitet.
pcntl_wait() gibt die Prozess ID des beendeten Kindes zurück, -1 im Fehlerfall oder Null wenn WNOHANG als Option angegeben war (auf wait3 Systemen) und kein kind verfügbar war.
Wenn wait3 auf Ihrem System verfügbar ist (meist BSD-artige Systeme) können Sie den optionalen options Parameter angeben. Wenn dieser Parameter nicht angegeben wurde, wird wait als Systemaufruf verwendet. Wenn wait3 nicht verfügbar ist, wird die Angabe eines Wertes für options keinerlei Auswirkungen haben. Der Wert von options ist der Wert von Null oder mehr der folgenden durch OR verknüpften beiden Konstanten:
| WNOHANG | kehre umgehend zurück, wenn kein Kind beendet wurde. |
| WUNTRACED | kehre für Kinder zurück die gestoppt sind und für solche, deren Status nicht gemeldet ist. |
pcntl_wait() speichert Statusinformationen im Parameter status , welcher durch die folgenden Funktionen ausgewertet werden kann: pcntl_wifexited(), pcntl_wifstopped(), pcntl_wifsignaled(), pcntl_wexitstatus(), pcntl_wtermsig() und pcntl_wstopsig().
Hinweis: Diese Funktion ist gleichwertig zum Aufruf der Funktion pcntl_waitpid() mit -1 als pid und keinerlei options .
Siehe auch pcntl_fork(), pcntl_signal(), pcntl_wifexited(), pcntl_wifstopped(), pcntl_wifsignaled(), pcntl_wexitstatus(), pcntl_wtermsig(), pcntl_wstopsig() und pcntl_waitpid().
pcntl_wait
24-Mar-2006 07:19
20-Feb-2006 12:39
This a simple multi process application where you can choose
the maximun process that can run at the same time.
This is useful when you need to limit the fork of process.
When the MAXPROCESS is reached the program wait on pcntl_wait()
<?php
DEFINE(MAXPROCESS,25);
for ($i=0;$i<100;$i++){
$pid = pcntl_fork();
if ($pid == -1) {
die("could not fork");
} elseif ($pid) {
echo "I'm the Parent $i\n";
$execute++;
if ($execute>=MAXPROCESS){
pcntl_wait($status);
$execute--;
}
} else {
echo "I am the child, $i pid = $pid \n";
sleep(rand(1,3));
echo "Bye Bye from $i\n";
exit;
}
}
?>
19-Oct-2005 02:14
Below is a simple example of forking some children and timing the total duration (useful for stress tests).
<?php
$isParent = true;
$children = array();
$start = microtime( true);
/* Fork you!
* (Sorry, I had to)
*/
$ceiling = $CONCURRENCY - 1;
for ( $i = 0; (( $i < $ceiling) && ( $isParent)); $i++) {
$pid = pcntl_fork();
if ( $pid === 0) {
$isParent = false;
} elseif ( $pid != -1) {
$children[] = $pid;
}
}
/* Process body */
echo "Do stuff here\n";
/* Cleanup */
if ( $isParent) {
$status = null;
while ( count( $children)) {
pcntl_wait( $status);
array_pop( $children);
}
echo "Completed in " . ( microtime( true) - $start) . " seconds.\n";
}
?>
