关于declare和posix_signal_dispatch()的验证和说明

haotian

下面都是自己程序验证的,如果有说的不对的, 请指出
验证原因:之前自己看workerman源码,写相关的信号,进程程序,模仿网上开始写,碰到declare(ticks=1),查资料说是让进程自己检测信号,数字是隔多少时间检测多少,今天碰巧看到workerman信号分发那段代码,发现使用了一个函数posix_signal_dispatch(),资料说该函数是:调用等待信号的处理器,也摸不着头绪这个函数到底是干嘛的
测试代码一:

echo "安装信号处理器...\n";
echo "父进程: ".posix_getpid()."\n";
pcntl_signal(SIGHUP, function($signo) {
    echo posix_getpid()." 信号处理器被调用\n";
});

$pid = pcntl_fork();
if($pid){
    //parent
    echo "这里是父进程".posix_getpid()."\n";
    echo "刚刚新建了子进程".$pid."\n";
    posix_kill($pid, SIGHUP);
}else{
    echo "我是子进程".posix_getpid()."\n";
}
//pcntl_signal_dispatch();
echo "完成\n";

这段代码里面我没有使用declare和pcntl_signal_dispatch,可以发现处理信号函数并没有被触发

测试代码二

declare(ticks=1);
echo "安装信号处理器...\n";
echo "父进程: ".posix_getpid()."\n";
pcntl_signal(SIGHUP, function($signo) {
    echo posix_getpid()." 信号处理器被调用\n";
});

$pid = pcntl_fork();
if($pid){
    //parent
    echo "这里是父进程".posix_getpid()."\n";
    echo "刚刚新建了子进程".$pid."\n";
    posix_kill($pid, SIGHUP);
}else{
    echo "我是子进程".posix_getpid()."\n";
}
echo "完成\n";

发现信号检测函数被触发了,这就说明declare(ticks=1);确实可以帮助进程检测接收到的信号
但是这个函数ticks后面的数值代表着基础代码执行了多少次后会被检测一次,基础代码是什么,如何检测,喜欢这块的可以自己查查
那么如果我们将ticks后面的数值调到1000,你就会发现信号又接收不到了,为什么,留给自己思考

测试代码三

echo "安装信号处理器...\n";
echo "父进程: ".posix_getpid()."\n";
pcntl_signal(SIGHUP, function($signo) {
    echo posix_getpid()." 信号处理器被调用\n";
});

$pid = pcntl_fork();
if($pid){
    //parent
    echo "这里是父进程".posix_getpid()."\n";
    echo "刚刚新建了子进程".$pid."\n";
    posix_kill($pid, SIGHUP);
}else{
    echo "我是子进程".posix_getpid()."\n";
}
pcntl_signal_dispatch();
echo "完成\n";

这里发现信号触发函数也被触发了,因为这个函数的作用就是检测当前进程有没有接收到信号,如果有,就按照信号处理函数之前已经绑定的处理方法进行处理

测试代码

echo "安装信号处理器...\n";
echo "父进程: ".posix_getpid()."\n";
pcntl_signal(SIGHUP, function($signo) {
    echo posix_getpid()." 信号处理器被调用\n";
});

$pid = pcntl_fork();
if($pid){
    //parent
    echo "这里是父进程".posix_getpid()."\n";
    echo "刚刚新建了子进程".$pid."\n";
    sleep(1);
    posix_kill($pid, SIGHUP);
}else{
    echo "我是子进程".posix_getpid()."\n";
}
pcntl_signal_dispatch();
sleep(2);
echo "完成\n";

这个稍微有个小改动就是让主进程睡了一秒,(听了@walkor的意见)但是在接受消息之后子进程和父进程都睡两秒,这样就排除了子进程已经结束,父进程发送信号没有接受者
然后再发送信息,这样做主进程就在子进程调用dispatch函数之后才发送了信息,我做这个主要就是为了验证,dispatch是一个让进程一直持有的状态,还是只执行一个动作,结果就是子进程没有接收到信号

3479 3 0
3个评论

haotian

@walkor 请看看这么验证的是否正确

  • 暂无评论
walkor

总结的很好,都正确。
不过子进程最好sleep下,因为主进程运行posix_kill($pid, SIGHUP)的时候,子进程可能已经退出了

  • 暂无评论
左岸的小熊

子进程已死

  • 暂无评论
年代过于久远,无法发表评论

haotian

1955
积分
0
获赞数
0
粉丝数
2017-02-10 加入
🔝