note 70161 added to function.pcntl-signal

From: 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

« previous php.notes (#118074) next »