這篇文章給大家分享的是有關PHP程序員的信號處理案例的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
信號就是事件發生時,對進程的一種通知機制(也叫軟件中斷)。當一個進程收到信號后,內核會暫停該進程正在執行的代碼,并跳轉到對應的信號處理函數中,如果處理函數不中斷,執行完處理函數后,會繼續執行之前中斷的地方往下執行。
我們在FPM模式下寫代碼,不會遇到信號處理相關的問題,但是CLI模式下一些常駐內存的腳本,如何能夠自由的重啟、關閉、退出前做一些清理工作(斷開鏈接,刪除臨時文件等)?
上圖中,我為信號SIGINT
注冊了處理函數sigint_handle
,捕獲到信號后,輸出內容后退出,簡單易懂吧。執行 gcc -o run run.c && ./run
,然后CTRL+C
(會觸發SIGINT
信號),成功輸出:成功捕獲到信號2!
,程序直接結束運行。
pcntl_signal
是PHP的信號處理注冊方法,上面實現的功能和C實現的基本一致,不同的是,當前進程不會退出,并且多輸出了一個signinfo
(PHP是C寫的,為啥剛剛C語言的沒有信號相關的信息呢?因為PHP使用的是另一個信號函數sigaction
,有興趣的可以了解一下)
這個是pcntl初始化的時候,將pcntl_signal_dispatch
注冊為tick的處理函數
pcntl_signal
會將處理函數放到信號集合中(PHP的hash table),而php_signale4
最終會調用sigaction
進行底層的信號管理。
這里我省略了大量代碼,將關鍵的點標記了出來,其實PHP維護一個自己的信號集合,每當調用pcntl_signal_dispatch
時就會查詢是否有信號,上面的SIG_BLOCK
會將信號阻塞,這樣只有我們把關鍵的代碼執行完畢之后,再去觸發信號處理函數以保證數據和程序邏輯的完整性。
經常見到身邊的程序員們,每當需要重啟PHP-FPM
進程的時候,使用的招數是kill掉所有PHP進程,然后新啟動。一般情況沒啥問題,但有些時候可能某個進程的任務還沒執行完,直接把人家中斷了略顯粗暴。其實只要你給PHP的Master進程發送一條USR2
信號,它便會再處理完所有任務后,重啟子進程,這才是所謂的優雅~
上圖是我簡單寫的一個例子,如果我們想讓進程優雅退出的時候,只需要發送SIGTERM
信號即可。需要注意的是SIGKILL
和SIGSTOP
信號會略過信號阻塞會將進程直接停止,還有就是信號會中斷睡眠(SLEEP),sleep
如果沒執行完會返回剩下的秒數,有興趣可以試試。
信號相關的知識點其實有很多,還需要繼續深入研究~上文中的PHP源碼為7.1.25版本,各個版本可能不太一樣。
感謝各位的閱讀!關于“PHP程序員的信號處理案例”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。