Hudzilla.org - the homepage of Paul Hudson
Contents > Miscellaneous topics > Process control Wish List | Report Bug | About Me ]

16.1.6     Event-driven child termination

This is NOT the latest copy of this book; click here for the latest version.

So far we've had to lock up our parent script while we wait for our children to finish executing, but we can combine the new-found knowledge of forking with the signals we saw earlier in this chapter to allow our parent process to execute freely until it gets notified that a child by the OS that a child finished.

To accomplish this feat we need to catch a new signal, SIGCHLD, which is sent when one or more child process has terminated. I say "one or more" on purpose: you may well get only one SIGCHLD call for several processes terminating, so you need to use the same pcntl_waitpid() while loop to ensure you catch them all in the same SIGCHLD handler.

So, what we're going to do is install a signal handler for SIGCHLD, use it to call pcntl_waitpid() to print out return information from the child scripts, then let the parent execute freely. Make sense? Good - here's how it looks in PHP:

<?php
    
declare(ticks = 1);

    
pcntl_signal(SIGCHLD, "signal_handler");

    function
signal_handler($signal) {
        switch(
$signal) {
            case
SIGCHLD:
                while (
pcntl_waitpid(0, $status) != -1) {
                    
$status = pcntl_wexitstatus($status);
                    echo
"Child $status completed\n";
                }

                exit;
        }
    }

    for (
$i = 1; $i <= 5; ++$i) {
        
$pid = pcntl_fork();

        if (!
$pid) {
            
sleep(1);
            print
"In child $i\n";
            exit(
$i);
        }
    }

    while(
1) {
        
// parent does processing here...
    
}
?>

The nice thing about that script is that it's simply a combination of our signal-handling script and our forking script: the only addition is the new SIGCHLD action. The advantages to forking this way should be clear: the parent process isn't left sitting around while the children are off doing cool stuff; instead, it can carry on processing a work load independently of its children, and gracefully handle child termination when ready. This actually works out as a smart way to write interactive applications: rather than have your users wait for an action to complete, why not fork it and let them continue using the parent, then notify them when the child has finished?

Author's Note: In the interest of balance, Tom Tromey (elite language hacker extraordinnaire) said that "wait and sigchld are one of the ugly warts on Unix". Go ahead and try it out, and see what you think.





<< 16.1.5 The third parameter to pcntl_waitpid()   16.1.7 Other ways to evaluate pcntl_waitpid()'s return value: pcntl_wifexited(), pcntl_wifsignaled(), pcntl_wifstopped(), pcntl_wtermsig(), and pcntl_wstopsig() >>
Table of Contents
Want to see this stuff in print? PHP in a Nutshell takes the core topics covered here, adds in thousands of edits from the editorial team and myself, and combines them to make an unbeatable reference for PHP programmers at all levels.



My latest book has hundreds more tips on how to use PHP, Apache, and MySQL, plus Perl, Python, shell scripts, performance tuning, and more!



Top-right shadow
 
Bottom-left shadow Bottom shadow

Comments from other readers
Be the first to add a comment to this chapter!



Add comment
Please note that by posting a comment here you are committing it to the public domain. This is important so that others can make use of your code themselves, and also so that I can incorporate helpful notes directly into the main text. Comments are limited to 2000 characters in length.

If you are reporting an error in the content, please tell me directly.

Your name/email address:
Your comment:
 
Now, in order to verify that you're a real person, please answer this simple question: what is six plus three?
The answer is:
(please write in
numbers, eg 19)


Top-right shadow
 
Bottom-left shadow Bottom shadow