Linux和PHP信号编程

    本文地址:http://tongxinmao.com/Article/Detail/id/76

    kill是unix/linux系统里被用得最多的一个信号发送工具,它默认发出SIGTERM的信号。TERM,就是terminal(终止)的意思。

    而使用ctrl+c终止一个进程的时候,一个SIGINT的信号会被发送给你所终止的程序

    另外一个大家可能用得比较多的就是HUP信号了。很多程序都会捕捉这个信号,重载配置。例如nginx就允许你kill -HUP pid来对nginx.conf进行重载。

    更多的信号,可以通过man signal或者man 3 signal或者阅读signal.h来获得。


    1.当运行parent process时,直接使用CTRL+C的方式可以正常结束parent process及其child process

    2.运行parent process,在另一个terminal模拟CTRL+C signal(kill -SIGINT PID)向parent shell发送,parent shell没有任何响应。

    3.运行parent process,在另一个terminal使用强制kill -SIGKILL PID向parent shell发送,结果造成child process成为孤儿进程。

    孤儿进程(orphan process)简单描述一下:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。

    通过以上测试,我们可以看到CTRL+C的动作及其与kill关系结论如下:
    CTRL+C向当前用户的进程组(process group,包括parent process,child process)中的child process的发送SIGINT signal,child process被终止后由系统再向parent process发送SIGINT signal,随之parent process被终止。所以单纯的使用kill -SIGINT是无法实现终止一个带有child process的parent process,使用kill -SIGKILL终止parent process,只会导致child process成为孤儿进程。所以如果向使用代码的方式终止带有child process的parent process,必须先将所有child process终止掉,才能让parent process终止。




    php的signal功能是使用pcntl_*系列函数来实现的。而为了保证效率,信号的捕捉是通过declare ticks来实现。很变态吧。由于declare ticks不能影响父文件,所以这个declare必须在最父级的文件里启用,这导致我们无法完美地封装某些功能块。

    function sighandler($signo) {

     switch ($signo) {
             case 
    SIGTERM:
                 
    // handle shutdown tasks
                 
    exit;
                 break;
             case 
    SIGHUP:
                 
    // handle restart tasks
                 
    break;
             case 
    SIGUSR1:
                 echo 
    "Caught SIGUSR1...\n";
                 break;
             default:
                 
    // handle all other signals
         
    }

    }

    declare(ticks=1);

    pcntl_signal(SIGINT, "sighandler");

    sleep(30);





    上一篇:单片机+CH375 USB打印机驱动
    下一篇:VIM命令