php pcntl_signal沒有效果是因為pcntl預設是會自動重新啟動被中斷的系統呼叫的,對外表現則是無法中斷系統呼叫的阻塞,其解決辦法就是設定不重啟系統呼叫即可。
本文操作環境:windows7系統、PHP7.1版、DELL G3電腦
php pcntl_signal沒有效果怎麼辦?
php的pcntl_signal用法及注意事項
最近需要做一個基於php的多進程server。為了優雅重啟,需要捕獲一下kill發出的SIGTERM訊號,於是用到了pcntl_signal。
剛開始發現捕捉訊號無效,無法進入訊號處理函數。研究了一下文檔,發現要運行一下declare(ticks = 1);看解釋說是為了產生時脈雲雲,我的理解就類似於晶振一樣。新增後父進程可以收到訊號了。
但是子進程還是無法收到訊號,排查了很久,沒看到什麼異常,子進程是平時阻塞噻socket_accept的,懷疑是不是系統調用在這裡無法中斷,於是改成while 1循環,可以順利進入中斷處理函數。
然後搜尋了一下,原來pcntl預設都是會自動重新啟動被中斷的系統呼叫的,對外表現則是無法中斷系統呼叫的阻塞。
這時回頭看手冊,原來pcntl_signal還有第三個參數,也是一個可選參數,就是讓我們決定是否自動重啟系統調用,選擇不重啟即可。
pcntl_signal函數簡介
(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)
pcntl_signal — 安裝一個訊號處理器
說明
pcntl_signal(int $signo, callback $handler, bool $restart_syscalls = true): bool
函數pcntl_signal()為signo指定的訊號安裝一個新的訊號處理器。
參數
signo
訊號編號。
handler
訊號處理器可以是使用者建立的函數或方法的名字,也可以是系統常數SIG_IGN(譯註:忽略訊號處理程序)或SIG_DFL(預設訊號處理程序).
注意:
注意當你使用一個物件方法的時候,該物件的參考計數回增加使得它在你改變為其他處理或腳本結束之前是持久存在的。
restart_syscalls
指定當訊號到達時系統呼叫重啟是否可用。 (譯註:經查資料,此參數意為系統呼叫被訊號打斷時,系統呼叫是否從開始處重新開始,但根據http://bugs.php.net/bug.php?id=52121,此參數存在bug無效。)
以上是php pcntl_signal沒有效果怎麼辦的詳細內容。更多資訊請關注PHP中文網其他相關文章!