php信号处理

时间:2019-08-07作者:klpeng分类:IT综合浏览:679评论:0

        信号是一种软中断,ipc通信中的一种,也是唯一的异步通信方式。在linux下,我们可以使用 kill -l 查看系统里面支持的所有信号,发送信号给某个进程可以使用 kill -信号类型 pid 给指定的pid。在php中,我们使用 posxi_kill 来实现信号的发送。

posix_kill向进程发送信号的几种作用:
        1、发送信号给指定的进程
            posix_kill("进程号",9);
        2、检测进程是否存活,返回true表示进程存在,反之返回false
            $res=posix_kill("进程号",0);
        3、向当前进程组发送信号,9强制退出,当然也可以使用常量 SIGKILL, 0是特殊的进程,表示进程组里面所有的进程。
            posix_kill(0,9);

在php中使用信号处理,在php5.3以前,使用declare语句来检测信号,我们来看demo1:

vim demo1
#!/usr/local/php/bin/php
<?php

declare(ticks = 1); 
pcntl_signal(SIGINT, function(){
	echo "信号触发\n";
});

$i=1;
while(true){
  $i++;
  echo $i,"\n";
  sleep(1);    
}

保存退出,设置脚本可执行并执行之

chmod +x demo1 && ./demo1

这时程序就会不断输出$i的值,我们使用 ctrl+c ,就会向当前进程发送信号,输出信号触发了,因为接管了信号,所以就没有退出。使用ctrl+\ 强制退出。

php信号处理

下面我们来看第二种方式demo2,使用pcntl_signal_dispatch 函数来实现,

#!/usr/local/php/bin/php
<?php
pcntl_signal(SIGINT, function(){
    echo "信号触发\n";
});

$i=0;
while(true){
  pcntl_signal_dispatch();
  $i++;
  echo $i,"\n";
  sleep(1);    
}

测试方式一样, 也是 ctrl+c ,ctrl+\ , 使用pcntl_signal_dispatch 会比 tick消耗更少的cpu。

第三种方式,在php7.1.0之后,新增了函数 pcntl_async_signals 来实现信号的处理,demo3

#!/usr/local/php/bin/php
<?php

pcntl_async_signals(true);

pcntl_signal(SIGINT, function(){
    echo "信号触发\n";
});


$i=0;
while(true){
  $i++;
  echo $i,"\n";
  sleep(1);    
}

测试方式一样, 也是 ctrl+c ,ctrl+\ , 采用异步信号的方式实现。由于php7.1.0还比较新,为了做兼容,我们可以这么写demo4:

#!/usr/local/php/bin/php
<?php

if(version_compare(PHP_VERSION, '7.1.0')>=0){
    pcntl_async_signals(true);
}

pcntl_signal(SIGINT, function(){
   echo "信号触发\n";
});


$i=0;
while(true){
    if(version_compare(PHP_VERSION, '7.1.0')<0){
        pcntl_signal_dispatch();
    }
    $i++;
    echo $i,"\n";
    sleep(1);    
}

注册多个信号的例子1:

#!/usr/local/php/bin/php
<?php

class Test
{
    public function handler($sig)
    {
        echo "信号值:" . $sig . "信号触发\n";
    }
    public function run()
    {
        pcntl_async_signals(true);
        pcntl_signal(SIGINT, [ & $this, "handler"]);
        pcntl_signal(SIGUSR1, [ & $this, "handler"]);
        pcntl_signal(SIGUSR2, [ & $this, "handler"]);
    }
}
$p1 = new Test();
$p1->run();

$i = 0;
while (true) {
    $i++;
    echo $i, "\n";
    sleep(1);
}

 当然也可以是静态类:

#!/usr/local/php/bin/php
<?php
class Test
{
    public static function handler($sig)
    {
        echo "信号值:" . $sig . "信号触发\n";
    }

    public static function run()
    {
        pcntl_async_signals(true);
        pcntl_signal(SIGINT, ['Test', "handler"]);
        pcntl_signal(SIGUSR1, ['Test', "handler"]);
        pcntl_signal(SIGUSR2, ['Test', "handler"]);
    }
}

Test::run();

$i = 0;
while (true) {
    $i++;
    echo $i, "\n";
    sleep(1);
}

 

打赏
文章版权声明:除非注明,否则均为彭超的博客原创文章,转载或复制请以超链接形式并注明出处。
相关推荐

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

猜你喜欢