PHP 5.6信号处理:声明(ticks = 1)vs pcntl_signal_dispatch()

时间:2017-10-08 10:06:36

标签: php daemon sigint sigterm

我正在用PHP 5.6编写一个守护进程。到目前为止,它基本上是一个Daemon类,其mainLoop()方法具有无限循环。在每次迭代中,mainLoop执行一系列步骤。

我需要它来实现“优雅的杀戮”机制:如果SIGINT或SIGTERM到达,守护进程必须在死亡之前完成当前迭代的当前步骤。

我的想法是默认使用静态变量Daemon::CONTINUE TRUE;当SIGINT或SIGTERM到达时,它被设置为FALSE。 在每次迭代中,在传递到下一步之前,守护进程检查self::CONTINUE是否已切换为FALSE,如果有,则返回。

我知道这样做的方法是使用pcntl_signal。我似乎可以将其与declare(ticks=1)pcntl_signal_dispatch()一起使用,但我不确定其区别。

declare(ticks=1)是否让进程检查每次滴答后信号的到达,而pcntl_signal_dispatch()只在我调用它时才明确检查信号?

这些是我之前描述的两种方式的片段。他们都是正确的吗?我应该使用哪一个?

方式1

<?php
declare(ticks=1) {
   pcntl_signal(SIGINT, function($signo) {Daemon::CONTINUE = FALSE;});
   pcntl_signal(SIGTERM, function($signo) {Daemon::CONTINUE = FALSE;});
}

public class Daemon {
   public static $CONTINUE = TRUE;

   function mainLoop() {
      ...
      if (self::CONTINUE === FALSE)
        return;
      ...
   }
}

方式2

<?php

pcntl_signal(SIGINT, function($signo) {Daemon::CONTINUE = FALSE;});
pcntl_signal(SIGTERM, function($signo) {Daemon::CONTINUE = FALSE;});

public class Daemon {
   public static $CONTINUE = TRUE;

   function mainLoop() {
      ...
      pcntl_signal_dispatch();
      if (self::CONTINUE === FALSE)
        return;
      ...
   }
}

感谢您的支持。

1 个答案:

答案 0 :(得分:0)

好的,经过一些测试和调试后我尝试了两种解决方案。 如果有人遇到同样的问题,我会留下我的意见。

似乎 way 1 with declare(ticks = 1)不起作用;我不明白为什么。
与pcntl_signal_dispatch()的方式2 相反,似乎很好用。

经过深入研究,我认为无论如何,2对我的案例来说是最好的方式 实际上,声明(tick = 1),如果有效,将在每个tick上运行pcntl_signal,大致对应于每个代码行的执行。 这可能会降低性能。

相反,显然pcntl_signal_dispatch只是在调用时处理挂起的信号,因此它的性能应该更轻。