PHP sleep,pcntl_signal和ticks

时间:2014-04-11 00:40:52

标签: php sleep pcntl

好的,所以我一直试图让Process Signals使用PHP脚本。我遇到了很多我不确定发生了什么的事情,我觉得文档并没有很好地解释它。

因此,我要按照registering signals上的示例:

<?php
// tick use required as of PHP 4.3.0
declare(ticks = 1);

// signal handler function
function sig_handler($signo)
{

     switch ($signo) {
         case SIGTERM:
             // handle shutdown tasks
             exit;
             break;
         case SIGHUP:
             // handle restart tasks
             break;
         case SIGUSR1:
             echo "Caught SIGUSR1...\n";
             break;
         default:
             // handle all other signals
     }

}

echo "Installing signal handler...\n";

// setup signal handlers
pcntl_signal(SIGTERM, "sig_handler");
pcntl_signal(SIGHUP,  "sig_handler");
pcntl_signal(SIGUSR1, "sig_handler");

// or use an object, available as of PHP 4.3.0
// pcntl_signal(SIGUSR1, array($obj, "do_something"));

echo"Generating signal SIGTERM to self...\n";

// send SIGUSR1 to current process id
posix_kill(posix_getpid(), SIGUSR1);

echo "Done\n";

?>

但是,在我的sig_handler函数中,我在最后添加了exit(1)echo "Done\n";仍然会被执行吗?我尝试了类似的东西,虽然是在类结构中,并且只有我的sig_handler被调用。

我的班级__construct调用函数registerSignals

private function registerSignals(){
    if(function_exists("pcntl_signal")){
        //call_user_func([$this, "sigintCleanup"]);
        pcntl_signal(SIGINT, [$this, "sigintCleanup"]);
        pcntl_signal(SIGTERM, [$this, "sigtermCleanup"]);
        pcntl_signal(SIGHUP, [$this, "sighupCleanup"]);
        pcntl_signal(SIGUSR1, [$this, "sigusr1Cleanup"]);
    }
}

protected function sigintCleanup(){
    echo "In SIGINT cleanup\n";
    $this->cleanup();
}

protected function sigtermCleanup(){
    echo "In SIGTERM cleanup\n";
    $this->cleanup();
}

protected function sighupCleanup(){
    echo "In SIGHUP cleanup\n";
    $this->cleanup();
}

protected function sigusr1Cleanup(){
    echo "In SIGUSR1 cleanup\n";
    $this->cleanup();
}

protected function cleanup(){
    echo "Shutting down\n";
    exit(1);
}

然后在我对此过程的测试中,我做了一些简单的sleepecho s(start只是在构造和信号注册完成后调用的函数):

function start(){
    echo "-- Testing the test script --\n";
    sleep(10000);
    echo "given how ticks work, this might not be called...\n";
    echo "\nAfter sleep... this should not be executed if there was a signal interrupt.\n";
}

所以我在ctl-c期间使用sleep。我的结果?

-- Testing the test script --
^Cgiven how ticks work, this might not be called...

After sleep... this should not be executed if there was a signal interrupt.
In SIGINT cleanup
Shutting down

正如您从echo中看到的那样,我有点想象ticks工作负责在处理信号之前完成start函数的方式。我仍然认为情况可能如此。事实是,我只是不知道。

我确实在我的程序顶部声明了ticks

declare(ticks = 1);

不立即处理信号对我来说是个问题。例如,如果我在start函数中使用了这段代码(并且我已对此进行了测试),该怎么办?

$count = 0;
while(true){
    count++;
    echo "count\n";
    sleep(5);
}

即使我的cleanup函数有exit,我仍然没有达到,因为SIGINT只是把我从sleep中拉出来,我继续循环并开始再次sleep

所以,我的问题是:signal如何在PHP处理工作?我如何保证当我收到信号时,会立即处理?我不想要一些能解决这个问题的代码,我想要一个解释(或者至少是一个好的和一个摘要的链接)。

PHP版本:5.4.22

操作系统:Ubuntu 12.10

1 个答案:

答案 0 :(得分:-1)

sleep()将会被某些信号击倒,并且它将返回左睡眠秒数,你可以做这样的事情让它保持睡眠状态。

.....
declare(ticks = 1);

$left = sleep(1000)
while ($left > 0) {
   $left = sleep($left);
}