note 70161 added to function.pcntl-signal
| From: | imslushie at hotmaildotcom dot com | Date: | Thu, 05 Oct 2006 02:16:15 +0000 |
| Subject: | note 70161 added to function.pcntl-signal | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-118074@lists.php.net to get a copy of this message | ||
I have been having trouble reaping my child process. It seemed most of the time, children were
reaped properly but *sometimes* they would stay as zombies. I was catching the CHLD signal to reap
child processes with the following code:
<?php
function childFinished($signal)
{
global $kids;
$kids--;
pcntl_waitpid(-1, $status);
}
$kids = 0;
pcntl_signal(SIGCHLD, "childFinished");
for ($i = 0; $i < 1000; $i++)
{
while ($kids >= 50) sleep(1);
$pid = pcntl_fork();
if ($pid == -1) die('failed to fork :(');
/* child process */
if ($pid == 0)
{
/* do something */
exit(0);
}
/* parent */
else { $kids++; }
}
/* when finished, just clean up the children */
print "Reaping $kids children...\n";
while ($kids) sleep(1);
print "Finished.\n";
?>
The problem was, $kids never became zero so it would effectively wait forever. After wracking my
brains (UNIX forks are new to me) I finally read the Perl IPC docs and viola, a solution! It turns
out that because signal handlers are not re-entrant, my handler will not be called again while it is
in use. The scenario that caused me trouble was that one child would exit and call the signal
handler, which would pcntl_waitpid() it and decrement the counter. Meanwhile, another child would
exit while the first child was still being reaped, so the second would never get to notify the
parent!
The solution was to continually reap children from the SIGCHLD handler, so long as there were
children to reap. Here is the *fixed* childFinished function:
<?php
function childFinished($signal)
{
global $kids;
while( pcntl_waitpid(-1, $status, WNOHANG) > 0 )
$kids--;
}
?>
----
Server IP: 216.194.113.175
Probable Submitter: 68.192.1.219
----
Manual Page -- http://www.php.net/manual/en/function.pcntl-signal.php
Edit -- https://master.php.net/note/edit/70161
Del: integrated -- https://master.php.net/note/delete/70161/integrated
Del: useless -- https://master.php.net/note/delete/70161/useless
Del: bad code -- https://master.php.net/note/delete/70161/bad+code
Del: spam -- https://master.php.net/note/delete/70161/spam
Del: non-english -- https://master.php.net/note/delete/70161/non-english
Del: in docs -- https://master.php.net/note/delete/70161/in+docs
Del: other reasons-- https://master.php.net/note/delete/70161
Reject -- https://master.php.net/note/reject/70161
Search -- https://master.php.net/manage/user-notes.php