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;
}
}