【问题标题】:PHP 5.6 signal handling: declare(ticks=1) vs pcntl_signal_dispatch()PHP 5.6 信号处理:declare(ticks=1) vs pcntl_signal_dispatch()
【发布时间】:2018-03-19 16:27:27
【问题描述】:

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

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

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

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

declare(ticks=1) 是否在每个滴答后检查信号的到达,而 pcntl_signal_dispatch() 仅在我调用它时才显式检查信号?

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

方式 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;
      ...
   }
}

感谢您的支持。

【问题讨论】:

    标签: php daemon sigint sigterm


    【解决方案1】:

    好的,经过一些测试和调试,我尝试了两种解决方案。 我会在这里留下我的观察,以防有人遇到我同样的问题。

    看来方式1和declare(ticks=1) 不起作用;我不明白为什么。
    相反,带有 pcntl_signal_dispatch() 的 方式 2 似乎效果不错。

    经过深入研究,无论如何,我认为方式 2 是最适合我的情况。
    事实上,declare(tick=1),如果有效的话,会在每个tick上运行pcntl_signal,大致对应每行代码的执行。 这可能会降低性能。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-29
      • 1970-01-01
      • 2015-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多