Question

I have some code like this, and I want to understand how does fork work, but I'm confused with declare(ticks=1). when I put it in the first line, after the child process finished, the signal handler will be called, which is what I want; but when I remove it, the signal handler will never be called! So, I want to know how does the ticks influence the signal processing.

<?php
declare(ticks=1);
function sigHandler($signal)
{
    echo "a child exited\n";
}
pcntl_signal(SIGCHLD, sigHandler, false);
echo "this is " . posix_getpid() . PHP_EOL;
for($i=0; $i<3; $i++)
{
    $pid = pcntl_fork();
    if($pid == -1) 
    {   
        echo 'fork failed ' . PHP_EOL;
    }   
    else if($pid)
    {   
    }   
    else
    {   
        $pid = posix_getpid();
        echo 'child ' . $pid . ' ' . time() . PHP_EOL;
        sleep(rand(2,5));
        echo 'child ' . $pid . ' done ' . time() . PHP_EOL;
        exit(0);
    }   
}
do
{
    $pid = pcntl_wait($status); 
    echo 'child quit ' . $pid . PHP_EOL;
}while($pid > 0); 
echo 'parent done' . PHP_EOL;
?>
Was it helpful?

Solution

Minor observation (quote the function name pls.):

pcntl_signal(SIGCHLD, 'sigHandler', false);

There are two different APIs involved.

  • The pcntl_wait() call is blocking until it gets an notification from the kernel.
  • The interrupt handling is an event loop inside the PHP interpreter. This is a hack feature and as of PHP5.3, there is a better way to do it ~ pcntl_signal_dispatch().
    • To answer to question, having declare ticks is like turning your mobile ringtone ON, or otherwise you never notice incoming calls.
    • The PHP5.3 method is much better engineering, and alot more controllable.
    • The default signal handler for most signals is sigignore, which receives the interrupt and does nothing. As you have registered the user handler I doubt this is being used.
    • I have never been able to discover the default value for the ticks, when not set directly.
    • Setting ticks to a small value does make scripts abit run slower, but you need to be doing heavy processing and monitoring to notice this. It makes a less predictable execution cost, I guess due to copying things around in the stack.
    • Without declare ticks or pcntl_signal_dispatch(), the signal is never picked up. If you are writing simple webpages, which terminate quickly; this may be the most sensible policy.
    • declare ticks needs to be tested carefully, as it has confusing scope rules. The safest method to put it at the head of your first script, like use strict in Perl.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top