edoceo

Forking is a very useful tool when programming, this allows one primary process to execute & control multiple sub-processes. Done correctly, this can greatly improve performance.

The method is quite simple, a single code-script is executed and at some-point fork()s. This splits the running code at that point, and what follows is neat - both copies resume executing but from different points.

Here's some examples of how to use pcntl_fork() in PHP.

Install Signal Handler

$child_list = 0;
// this is required
// @see http://php.net/manual/en/function.pcntl-signal.php
declare(ticks = 1);
function sig_handler($sig)
{
    global $child_list;
    switch ($sig) {
    case SIGCHLD:
        $child_list--;
        while( ( $pid = pcntl_wait ( $sig, WNOHANG ) ) > 0 ){
            $x = pcntl_wexitstatus ( $sig );
        }
        break;
    }
}
pcntl_signal(SIGCHLD, 'sig_handler');

Create Fork Tree

Note that this forking process does not work inside mod_php. Also, some open connections (such as a database) will need to be re-established.

foreach ($list as $item) {
    // Fork
    $pid = pcntl_fork();
    switch ($pid) {
    case -1: // Error
        die('Fork failed, your system is b0rked!');
        break;
    case 0: // Child
        // Remove Signal Handlers in Child
        pcntl_signal(SIGCHLD,SIG_DFL);
        do_long_process_in_this_function_here($item);
        exit(0);
        break;
    default: // Parent
        echo "run: $child_list processes\n";
        if ($child_list >= 10) {
            // Just wait for one to die
            pcntl_wait($x);
            $child_list--;
        }
        $child_list++;
        break;
    }
}

Loading Comments from Disqus...