• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    php 中的信号处理操作实例详解

    本文实例讲述了php 中的信号处理操作。分享给大家供大家参考,具体如下:

    首先我们需要了解几个函数

    pcntl_signal   安装信号处理器,也就是当指定信号发生时,调用函数。
    pcntl_alarm   指定秒数后向进程发送SIGALRM信号。
    posix_getpid 返回当前进程id
    posix_kill       给指定进程发送信号

    一些常用的信号说明

    SIGHUP
    本信号在用户终端连接(正常或非正常)结束时发出, 通常是在终端的控制进程结束时,
    通知同一session内的各个作业, 这时它们与控制终端不再关联。

    SIGINT
    程序终止(interrupt)信号, 在用户键入INTR字符(通常是Ctrl-C)时发出。

    SIGQUIT
    和SIGINT类似,但由QUIT字符(通常是Ctrl-/)来控制;进程在因收到SIGQUIT退出时会产生core文件,
    在这个意义上类似于一个程序错误信号。

    SIGKILL
    用来立即结束程序的运行。本信号不能被阻塞、处理和忽略。如果管理员发现某个进程终止不了,可尝试发送这个信号。

    SIGTERM
    程序结束(terminate)信号, 与SIGKILL不同的是该信号可以被阻塞和处理。通常用来要求程序自己正常退出,
    shell命令kill缺省产生这个信号。如果进程终止不了,我们才会尝试SIGKILL。

    SIGUSR1
    留给用户使用

    SIGUSR2
    留给用户使用

    SIGALRM
    时钟定时信号, 计算的是实际的时间或时钟时间。alarm函数使用该信号。

    SIGCHLD
    子进程结束时, 父进程会收到这个信号。

    例1:

    ?php
    declare(ticks = 1);
    //信号处理函数
    function sig_func() {
      echo "child exit \r\n";
    }
    //设置信号处理器
    pcntl_signal(SIGCHLD, 'sig_func');
    $pid = pcntl_fork();
    if($pid == -1) {
      die('fork error');
    } else if ($pid) {
      pcntl_wait($status);
    } else {
      echo "child... \r\n";
      exit;
    }
    
    

    当子进程退出时,会向父进程发送SIGCHLD信号,我们通过设置信号处理器,成功的处理信号。

    例2:

    ?php
    declare(ticks = 1);
    //信号处理函数
    function sig_func($signo) {
      switch($signo) {
        case SIGCHLD: {
          echo "child SIGCHLD \r\n";
          break;
        }
        case SIGTERM: {
          echo "child SIGTERM \r\n";
          break;
        }
        default:
          //处理所有其他信号
          break;
      }
    }
    //设置信号处理器
    pcntl_signal(SIGCHLD, 'sig_func');
    //设置信号处理器
    pcntl_signal(SIGTERM, 'sig_func');
    $pid = pcntl_fork();
    if($pid == -1) {
      die('fork error');
    } else if ($pid) {
      pcntl_wait($status);
    } else {
      sleep(3);
      echo "child \r\n";
      sleep(3);
      posix_kill(getmypid(), SIGTERM);
      exit;
    }
    
    

    父进程等待子进程的退出,子进程等待3秒后输出child,再等待3秒后向自身发送结束程序信号。

    例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常见数据库操作技巧汇总》

    希望本文所述对大家PHP程序设计有所帮助。

    您可能感兴趣的文章:
    • python多线程下信号处理程序示例
    • PHP信号处理机制的操作代码讲解
    • 对Python信号处理模块signal详解
    • Golang信号处理及如何实现进程的优雅退出详解
    • Perl信号处理学习简单小结
    • 详细分析C++ 信号处理
    上一篇:php libevent 功能与使用方法详解
    下一篇:php多进程中的阻塞与非阻塞操作实例分析
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    php 中的信号处理操作实例详解 php,中的,信号处理,操作,