首頁 >後端開發 >php教程 >PHP程式設計師的訊號處理

PHP程式設計師的訊號處理

藏色散人
藏色散人轉載
2021-02-04 07:04:083267瀏覽

寫給PHP程式設計師的訊號處理教學

今天晚上吃滷煮,領桌的妹子問我,這玩意兒能吃麼?我:你覺得能吃就能吃。 。 。和內容無關的主題

什麼是訊號

訊號就是事件發生時,對進程的一種通知機制(也叫軟體中斷)。當一個行程收到訊號後,核心會暫停該行程正在執行的程式碼,並跳到對應的訊號處理函數中,如果處理函數不中斷,執行完處理函數後,會繼續執行之前中斷的地方往下執行。

我們在FPM模式下寫程式碼,不會遇到訊號處理相關的問題,但是CLI模式下一些常駐記憶體的腳本,如何能夠自由的重啟、關閉、退出前做一些清理工作(斷開鏈接,刪除臨時文件等)?

C的訊號處理範例

PHP程式設計師的訊號處理

#上圖中,我為訊號SIGINT註冊了處理函數sigint_handle,捕捉到訊號後,輸出內容後退出,簡單易懂。執行gcc -o run run.c && ./run ,然後CTRL C(會觸發SIGINT訊號),成功輸出:成功擷取到訊號2!,程式直接結束運行。

PHP的訊號處理範例

PHP程式設計師的訊號處理

#pcntl_signal是PHP的訊號處理註冊方法,上面實作的功能和C實現的基本一致,不同的是,當前進程不會退出,並且多輸出了一個signinfo(PHP是C寫的,為啥剛剛C語言的沒有信號相關的信息呢?因為PHP使用的是另一個訊號函數sigaction,有興趣的可以了解)

PHP的訊號處理並不是直接呼叫C

PHP程式設計師的訊號處理

##這個是pcntl初始化的時候,將

pcntl_signal_dispatch註冊為tick的處理函數

PHP程式設計師的訊號處理

##pcntl_signal

會將處理函數放到訊號集合中(PHP的hash table),而php_signale4最終會呼叫sigaction進行底層的訊號管理。

PHP程式設計師的訊號處理這裡我省略了大量程式碼,將關鍵的點標記了出來,其實PHP維護一個自己的訊號集合,每當呼叫

pcntl_signal_dispatch

時就會查詢是否有訊號,上面的SIG_BLOCK會將訊號阻塞,這樣只有我們把關鍵的程式碼執行完畢之後,再去觸發訊號處理函數以確保資料和程式邏輯的完整性。 PHP如何優雅的處理訊號

經常見到身邊的程式設計師們,每當需要重啟

PHP-FPM

進程的時候,使用的招數是kill掉所有PHP進程,然後新啟動。一般情況沒啥問題,但有些時候可能某個行程的任務還沒執行完,直接把人家中斷了略顯粗暴。其實只要你給PHP的Master進程發送一條USR2訊號,它就會再處理完所有任務後,重啟子進程,這才是所謂的優雅~

PHP程式設計師的訊號處理上圖是我簡單寫的一個例子,如果我們想讓進程優雅退出的時候,只需要發送

SIGTERM

訊號即可。要注意的是SIGKILLSIGSTOP訊號會略過訊號阻塞會將行程直接停止,還有就是訊號會中斷睡眠(SLEEP),sleep如果沒執行完會回傳剩下的秒數,有興趣可以試試看。 訊號相關的知識點其實很多,還需要繼續深入研究~上文中的PHP原始碼為7.1.25版本,各個版本可能不太一樣。

以上是PHP程式設計師的訊號處理的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除