新聞中心
“ 今天晚上吃鹵煮,領(lǐng)桌的妹子問我,這玩意兒能吃么?我:你覺得能吃就能吃。。。和內(nèi)容無關(guān)的主題 ”

目前成都創(chuàng)新互聯(lián)公司已為近1000家的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)頁空間、網(wǎng)站托管、服務(wù)器托管、企業(yè)網(wǎng)站設(shè)計(jì)、豐澤網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。
01
什么是信號(hào)
信號(hào)就是事件發(fā)生時(shí),對(duì)進(jìn)程的一種通知機(jī)制(也叫軟件中斷)。當(dāng)一個(gè)進(jìn)程收到信號(hào)后,內(nèi)核會(huì)暫停該進(jìn)程正在執(zhí)行的代碼,并跳轉(zhuǎn)到對(duì)應(yīng)的信號(hào)處理函數(shù)中,如果處理函數(shù)不中斷,執(zhí)行完處理函數(shù)后,會(huì)繼續(xù)執(zhí)行之前中斷的地方往下執(zhí)行。
我們?cè)贔PM模式下寫代碼,不會(huì)遇到信號(hào)處理相關(guān)的問題,但是CLI模式下一些常駐內(nèi)存的腳本,如何能夠自由的重啟、關(guān)閉、退出前做一些清理工作(斷開鏈接,刪除臨時(shí)文件等)?
02
C的信號(hào)處理舉例
上圖中,我為信號(hào)SIGINT注冊(cè)了處理函數(shù)sigint_handle,捕獲到信號(hào)后,輸出內(nèi)容后退出,簡(jiǎn)單易懂吧。執(zhí)行 gcc -o run run.c && ./run ,然后 CTRL+C(會(huì)觸發(fā)SIGINT信號(hào)) ,成功輸出: 成功捕獲到信號(hào)2! ,程序直接結(jié)束運(yùn)行。
03
PHP的信號(hào)處理舉例
pcntl_signal是PHP的信號(hào)處理注冊(cè)方法,上面實(shí)現(xiàn)的功能和C實(shí)現(xiàn)的基本一致,不同的是,當(dāng)前進(jìn)程不會(huì)退出,并且多輸出了一個(gè)signinfo(PHP是C寫的,為啥剛剛C語言的沒有信號(hào)相關(guān)的信息呢?因?yàn)镻HP使用的是另一個(gè)信號(hào)函數(shù) sigaction, 有興趣的可以了解一下 )
04
PHP的信號(hào)處理并不是直接調(diào)用C
這個(gè)是pcntl初始化的時(shí)候,將pcntl_signal_dispatch注冊(cè)為tick的處理函數(shù)
pcntl_signal會(huì)將處理函數(shù)放到信號(hào)集合中(PHP的hash table),而php_signale4最終會(huì)調(diào)用sigaction進(jìn)行底層的信號(hào)管理。
這里我省略了大量代碼,將關(guān)鍵的點(diǎn)標(biāo)記了出來,其實(shí)PHP維護(hù)一個(gè)自己的信號(hào)集合,每當(dāng)調(diào)用 pcntl_signal_dispatch時(shí)就會(huì)查詢是否有信號(hào),上面的SIG_BLOCK會(huì)將信號(hào)阻塞,這樣只有我們把關(guān)鍵的代碼執(zhí)行完畢之后,再去觸發(fā)信號(hào)處理函數(shù)以保證數(shù)據(jù)和程序邏輯的完整性。
05
PHP如何優(yōu)雅的處理信號(hào)
經(jīng)常見到身邊的程序員們,每當(dāng)需要重啟PHP-FPM進(jìn)程的時(shí)候,使用的招數(shù)是kill掉所有PHP進(jìn)程,然后新啟動(dòng)。一般情況沒啥問題,但有些時(shí)候可能某個(gè)進(jìn)程的任務(wù)還沒執(zhí)行完,直接把人家中斷了略顯粗暴。其實(shí)只要你給PHP的Master進(jìn)程發(fā)送一條USR2信號(hào),它便會(huì)再處理完所有任務(wù)后,重啟子進(jìn)程,這才是所謂的優(yōu)雅~
上圖是我簡(jiǎn)單寫的一個(gè)例子,如果我們想讓進(jìn)程優(yōu)雅退出的時(shí)候,只需要發(fā)送SIGTERM信號(hào)即可。需要注意的是SIGKILL和SIGSTOP信號(hào)會(huì)略過信號(hào)阻塞會(huì)將進(jìn)程直接停止,還有就是信號(hào)會(huì)中斷睡眠(SLEEP),sleep如果沒執(zhí)行完會(huì)返回剩下的秒數(shù),有興趣可以試試。
信號(hào)相關(guān)的知識(shí)點(diǎn)其實(shí)有很多,還需要繼續(xù)深入研究~上文中的PHP源碼為7.1.25版本,各個(gè)版本可能不太一樣,如果覺得學(xué)到了點(diǎn)啥,順手點(diǎn)個(gè)好看
名稱欄目:寫給PHP程序員的信號(hào)處理教程
瀏覽地址:http://m.5511xx.com/article/dhgoejp.html


咨詢
建站咨詢
