• PHP系统编程--PHP进程信号处理(转)


    原地址:https://www.cnblogs.com/linzhenjie/p/5485436.html

    PHP的pcntl扩展提供了信号处理的功能,利用它可以让PHP来接管信号的处理,在开发服务器端守护进程方面,信号处理至关重要。

    函数原型

    bool pcntl_signal(int $signo ,callback $handler [,bool $restart_syscalls=true])

    第一个参数是信号ID 
    第二个参数是信号发生时回调的PHP函数。 
    第三个参数是是否restart,是否重新注册此信号。这个参数如果为false,那此信号只注册处理一次。

    pcntl_signal的实现

    <?php
    //信号处理需要注册ticks才能生效,这里务必注意
    //PHP5.4以上版本就不再依赖ticks了
    declare(ticks = 1);
    function sig_handler($signo){
        switch ($signo) {
            case SIGUSR1: echo "SIGUSR1
    "; break;
            case SIGUSR2: echo "SIGUSR2
    "; break;
            default:      echo "unknow";    break;
        }
    }
    //安装信号触发器器
    pcntl_signal(SIGUSR1, "sig_handler");
    pcntl_signal(SIGUSR2, "sig_handler");
    //向当前进程发送SIGUSR1信号
    posix_kill(posix_getpid(), SIGUSR1);
    posix_kill(posix_getpid(), SIGUSR2);
    ?>

    执行此代码会在终端输出你想要的结果,其实官方的pcntl_signal性能极差,主要是PHP的函数无法直接注册到操作系统信号设置中,所以pcntl信号需要依赖tick机制来完成。 
    pcntl_signal的实现原理是,触发信号后先将信号加入一个队列中。然后在PHP的ticks回调函数中不断检查是否有信号,如果有信号就执行PHP中指定的回调函数,如果没有则跳出函数。 
    ticks=1表示每执行1行PHP代码就回调此函数。实际上大部分时间都没有信号产生,但ticks的函数一直会执行。 
    比较好的做法是去掉ticks,转而使用pcntl_signal_dispatch,在代码循环中自行处理信号。

    pcntl_signal_dispatch的实现

    <?php
    // 定义一个处理器,接收到SIGINT信号后只输出一行信息
    function signalHandler($signo) {
        switch ($signo) {
            case SIGUSR1: echo "SIGUSR1
    "; break;
            case SIGUSR2: echo "SIGUSR2
    "; break;
            default:      echo "unknow";    break;
        }
    }
    //安装信号触发器器
    pcntl_signal(SIGINT, 'signalHandler');
    while (true) {
        sleep(1);
        posix_kill(posix_getpid(), SIGUSR1);
        pcntl_signal_dispatch(); //接收到信号时,调用注册的signalHandler()
    }

    实战:用信号来处理函数超时

    <?php
    function a(){
        sleep(10);
        echo "OK
    ";
    }
    function b(){
        echo "Stop
    ";
    }
    function c(){
        usleep(100000);
    }
    //信号处理代码
    function sig(){
        throw new Exception;
    }
    try{
        pcntl_alarm(2); //设定超时后触发的信号
        pcntl_signal(SIGALRM, "sig");
        pcntl_signal_dispatch();
        a();
        pcntl_alarm(0);
    }catch(Exception $e){
        echo "timeout
    ";
    }
    b();
    a(); //等待十秒后完成
    b();
  • 相关阅读:
    H5 通过腾讯地图api定点位置
    常见的css的效果--箭头--三角形--条纹
    vue+element 给表格添加数据,页面不实时刷新的问题
    js 压缩图片
    利用NBI可视化+influxDB时序数据库构建物联网大数据分析平台
    利用NBI大数据可视化工具做RFM模型分析,洞察数据价值,驱动业务增长
    利用Python+NBI大数据可视化工具实现采集到分析整体方案
    类库封装log4net
    浅析Golang的线程模型与调度器
    Python字符串转换为日期时间– strptime
  • 原文地址:https://www.cnblogs.com/loveyouyou616/p/8854835.html
Copyright © 2020-2023  润新知