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命令