2017-10-08 79 views
0

我正在PHP 5.6编写一个守护进程。到目前为止,它基本上是一个Daemon类,具有无限循环的mainLoop()方法。在每次迭代中,mainLoop执行一系列步骤。我需要它来实现一个“优雅的杀死”机制:如果SIGINT或SIGTERM到达,守护进程必须在死前完成当前迭代的当前步骤。PHP 5.6信号处理:declare(ticks = 1)vs pcntl_signal_dispatch()

我的想法是默认使用静态变量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

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

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

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

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