phpsignalsposixpcntl

PHP pcntl_signal callbacks are not called


This is the complete reproducible code.

<?php
class console{
    public static function log($msg, $arr=array()){
        $str = vsprintf($msg, $arr);
        fprintf(STDERR, "$str\n");
    }
}
function cleanup(){
    echo "cleaning up\n";
}
function signal_handler($signo){
    console::log("Caught a signal %d", array($signo));
    switch ($signo) {
        case SIGTERM:
            // handle shutdown tasks
             cleanup();
            break;
        case SIGHUP:
            // handle restart tasks
            cleanup();
            break;
        default:
            fprintf(STDERR, "Unknown signal ". $signo);
    }
}

if(version_compare(PHP_VERSION, "5.3.0", '<')){
    // tick use required as of PHP 4.3.0
    declare(ticks = 1);
}

pcntl_signal(SIGTERM, "signal_handler");
pcntl_signal(SIGHUP, "signal_handler");

if(version_compare(PHP_VERSION, "5.3.0", '>=')){
    pcntl_signal_dispatch();
    console::log("Signal dispatched");
}

echo "Running an infinite loop\n";
while(true){
    sleep(1);
    echo date(DATE_ATOM). "\n";
}

When I run this I see the date values each second. Now if I press Ctrl+C cleanup function is not called. In fact signal_handler is not called.

Here is the sample output.

$ php testsignal.php 
Signal dispatched
Running an infinite loop
2012-10-04T13:54:22+06:00
2012-10-04T13:54:23+06:00
2012-10-04T13:54:24+06:00
2012-10-04T13:54:25+06:00
2012-10-04T13:54:26+06:00
2012-10-04T13:54:27+06:00
^C

Solution

  • The CTRL+C fires SIGINT, which you have not installed handler for:

    <?php
    ...
    function signal_handler($signo){
    ...
        case SIGINT:
            // handle restart tasks
            cleanup();
            break;
    ...
    }
    ...
    pcntl_signal(SIGINT, "signal_handler");
    ...
    

    Now it works:

    $ php testsignal.php
    Signal dispatched
    Running an infinite loop
    2012-10-08T09:57:51+02:00
    2012-10-08T09:57:52+02:00
    ^CCaught a signal 2
    cleaning up
    2012-10-08T09:57:52+02:00
    2012-10-08T09:57:53+02:00
    ^\Quit