我正在用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;
...
}
}
感谢您的支持。
答案 0 :(得分:0)
好的,经过一些测试和调试后我尝试了两种解决方案。 如果有人遇到同样的问题,我会留下我的意见。
似乎
与pcntl_signal_dispatch()的方式2 相反,似乎很好用。
经过深入研究,我认为无论如何,2对我的案例来说是最好的方式 实际上,声明(tick = 1),如果有效,将在每个tick上运行pcntl_signal,大致对应于每个代码行的执行。 这可能会降低性能。
相反,显然pcntl_signal_dispatch只是在调用时处理挂起的信号,因此它的性能应该更轻。