声明(ticks)和php中的信号处理程序之间的关系是什么

时间:2013-07-28 09:17:47

标签: php pcntl

我有一些像这样的代码,我想了解fork如何工作,但我与declare(ticks=1)混淆了。 当我把它放在第一行时,在子进程完成后,将调用信号处理程序,这就是我想要的;但当我删除它时,永远不会调用信号处理程序!所以,我想知道滴答声如何影响信号处理。

<?php
declare(ticks=1);
function sigHandler($signal)
{
    echo "a child exited\n";
}
pcntl_signal(SIGCHLD, sigHandler, false);
echo "this is " . posix_getpid() . PHP_EOL;
for($i=0; $i<3; $i++)
{
    $pid = pcntl_fork();
    if($pid == -1) 
    {   
        echo 'fork failed ' . PHP_EOL;
    }   
    else if($pid)
    {   
    }   
    else
    {   
        $pid = posix_getpid();
        echo 'child ' . $pid . ' ' . time() . PHP_EOL;
        sleep(rand(2,5));
        echo 'child ' . $pid . ' done ' . time() . PHP_EOL;
        exit(0);
    }   
}
do
{
    $pid = pcntl_wait($status); 
    echo 'child quit ' . $pid . PHP_EOL;
}while($pid > 0); 
echo 'parent done' . PHP_EOL;
?>

1 个答案:

答案 0 :(得分:10)

次要观察(引用函数名称pls。):

pcntl_signal(SIGCHLD, 'sigHandler', false);

涉及两种不同的API。

  • pcntl_wait()调用阻塞,直到它从内核收到通知。
  • 中断处理是PHP解释器内部的事件循环。这是一个黑客功能,从PHP5.3开始,有一种更好的方法可以做到这一点~pcntl_signal_dispatch()。
    • 要回答问题,声明刻度就像打开手机铃声一样,否则你就不会注意来电了。
    • PHP5.3方法工程更好,而且更可控。
    • 大多数信号的默认信号处理程序是sigignore,它接收中断并且什么也不做。正如您已注册用户处理程序,我怀疑这是否正在使用。
    • 如果没有直接设置,我从未能找到刻度线的默认值。
    • 将ticks设置为较小的值确实会使脚本abit运行得更慢,但是您需要进行繁重的处理和监视才能注意到这一点。它的执行成本不太可预测,我想是因为在堆栈中复制了一些东西。
    • 如果没有声明滴答或pcntl_signal_dispatch(),则不会拾取信号。如果您正在编写简单的网页,它会快速终止;这可能是最明智的政策。
    • 声明刻度需要仔细测试,因为它具有令人困惑的范围规则。将它放在第一个脚本的最安全的方法,比如Perl中的 use strict