|
Posted by petersprc on 11/19/06 10:16
Hi,
The OS keeps the zombie around in case the parent process eventually
decides to retrieve the child's exit status information. You can tell
the OS you're not interested and to not keep zombies around using this:
pcntl_signal(SIGCHLD, SIG_IGN);
You could also trap SIGCHLD and check the child's exit status:
function sigchld($signo) {
while (($pid = pcntl_waitpid(-1, $status, WNOHANG)) > 0) {
echo "Child with PID $pid returned " .
pcntl_wexitstatus($status) . ".\n";
}
}
pcntl_signal(SIGCHLD, 'sigchld');
Thomas wrote:
> I'm having some issues with forking and defunct children. This is my code:
>
> #!/usr/bin/php
> <?php
> $socket = stream_socket_server("tcp://0.0.0.0:8000", $errno, $errstr);
>
> /*
> * LISTEN FOR CONNECTIONS
> */
> while(TRUE){
> while($conn = stream_socket_accept($socket,-1)){
> $pid = pcntl_fork();
> if($pid==-1){
> fwrite(STDOUT,"Fork failed. Exiting!\n");
> exit;
> }elseif($pid){
> /*
> * We are parent.
> * Close connection
> */
> fclose($conn);
> }else{
> fwrite($conn, "Hello!\n");
> fwrite($conn, "I am PID: ".posix_getpid()."\n");
> sleep(2);
> fclose($conn);
> exit;
> }
> }
> }
>
> function sig_handler($signo){
> switch ($signo) {
> case SIGTERM:
> exit;
> break;
> case SIGCHLD:
> exit;
> break;
> default:
> // handle all other signals
> }
> }
>
> // setup signal handlers
> pcntl_signal(SIGTERM, "sig_handler");
> pcntl_signal(SIGCHLD, "sig_handler");
> ?>
>
> When the child exits (after the 2 seconds sleep), it leaves a defunct
> zombie running ([scriptname] <defunct>), and I can't get rid of it
> unless I kill the parent script.
>
> What I'm hoping to accomplish is removing the child completely on exit.
> How can I do this?
>
> I've read the manual on pcntl_fork on php.net (and all the comments),
> but nothing seems to work. I know it's me doing something completely
> wrong, I just can't figure out what.
>
> I hope someone can point me in the right direction. :o)
>
> Regards
> Thomas
Navigation:
[Reply to this message]
|