例3:
<?php declare(ticks = 1); //信号处理函数 function sig_func($signo) { switch($signo) { case SIGCHLD: { echo "child SIGCHLD \r\n"; break; } /*这里要把处理SIGTERM信号的代码注释掉 case SIGTERM: { echo "child SIGTERM \r\n"; break; }*/ default: //处理所有其他信号 break; } } //设置信号处理器 pcntl_signal(SIGCHLD, 'sig_func'); //设置信号处理器,也注释掉 //不然当父进程发向子进程发送SIGTERM信号时,子进程不会退出,还会继续执行 //我们的信号处理函数把SIGTERM给忽略了 //pcntl_signal(SIGTERM, 'sig_func'); $pid = pcntl_fork(); if($pid == -1) { die('fork error'); } else if ($pid) { sleep(30); posix_kill($pid, SIGTERM); } else { $cnt = 0; for(;;) { sleep(3); echo $cnt, '-'; ++$cnt; } exit; }
父进程在等待30秒后,向子进程发送SIGTERM结束程序信号。如果我们设置了SIGTERM信号的处理器,并且在自定义信号处理器中并没有杀死该进程,则该子进程会一直运行下去。
pcntl_signal()函数仅仅是注册信号和它的处理方法,真正接收到信号并调用其处理方法的是pcntl_signal_dispatch()函数。
例4:
<?php //使用ticks需要PHP 4.3.0以上版本 //declare(ticks = 1); function sig_func() { echo "SIGALRM \r\n"; } //设置信号处理器 pcntl_signal(SIGALRM, 'sig_func'); pcntl_alarm(3);
通过函数pcntl_alarm()3秒后给进程发送SIGALRM信号,但信号处理函数并未调用。
原因是我们注释了declare(ticks = 1);这段代码,而又没有调用pcntl_signal_dispatch()函数。
declare(ticks = 1);表示每执行一条低级指令,就检查一次信号,如果检测到注册的信号,就调用其信号处理器。但是这种处理方式效率很低,建议在代码循环中通过pcntl_signal_dispatch()来处理信号。
<?php //使用ticks需要PHP 4.3.0以上版本 //declare(ticks = 1); function sig_func() { echo "SIGALRM \r\n"; } //设置信号处理器 pcntl_signal(SIGALRM, 'sig_func'); pcntl_alarm(3); //因为3秒后pcntl_alarm函数才会给进程发送SIGALRM信号 //所以我们通过sleep函数等待3秒后,调用pcntl_signal_dispatch()来处理信号 sleep(3); pcntl_signal_dispatch();
pcntl_signal_dispatch()这个函数是PHP5.3以上才支持的,如果你的PHP版本大于5.3,建议使用这个方法调用信号处理器。
5.3以下的版本需要在注册信号之前加上:declare(ticks = 1);
更多关于PHP相关内容感兴趣的读者可查看本站专题:《PHP进程与线程操作技巧总结》、《PHP网络编程技巧总结》、《PHP基本语法入门教程》、《PHP数组(Array)操作技巧大全》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》