2017-10-08 76 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)只是在調用待處理信號時處理,所以它應該在性能上更輕。