循環(huán)總體流程
部分流程圖和表格參考于《深入理解Nginx》
worker進(jìn)程循環(huán)在ngx_worker_process_cycle
函數(shù)中進(jìn)行等限,循環(huán)流程如圖所示遮婶。在Nginx源碼學(xué)習(xí)——優(yōu)雅的停止Nginx服務(wù)一文中描述過master進(jìn)程是如何通知子進(jìn)程終止的身腻。而通知到達(dá)的結(jié)果就是相應(yīng)全局變量值的改變:
信號(hào) | 全局標(biāo)志位變量 | 意義 |
---|---|---|
QUIT | ngx_quit | 優(yōu)雅的關(guān)閉進(jìn)程 |
TERM | ngx_terminate | 強(qiáng)制關(guān)閉進(jìn)程 |
USR1 | ngx_reopen | 重新打開所有文件 |
WINCH | ngx_debug_quit | 目前無實(shí)際意義 |
然后循環(huán)中,通過檢查全局變量的值來決定后續(xù)動(dòng)作。
worker進(jìn)程退出流程
ngx_worker_process_exit
函數(shù)執(zhí)行子進(jìn)程worker退出前的收尾工作鸵贬,并最終使子進(jìn)程退出。該函數(shù)工作流程如下:
子進(jìn)程終止后脖捻,將發(fā)送SIGCHLD
信號(hào)給 master
進(jìn)程阔逼,捕捉信號(hào)后觸發(fā)信號(hào)處理函數(shù)ngx_signal_handler
,進(jìn)而進(jìn)行對(duì)終止子進(jìn)程的善后處理:
if (signo == SIGCHLD) {
ngx_process_get_status();
}
ngx_process_get_status
函數(shù)負(fù)責(zé)善后處理地沮,流程如下:
Nginx服務(wù)器的是服務(wù)器編程的良好范例嗜浮。上述流程中,使用循環(huán)調(diào)用waitpid
的方式獲取終止子進(jìn)程的狀態(tài)摩疑。
for ( ;; ) {
pid = waitpid(-1, &status, WNOHANG); //WNOHANG告知危融,在尚有未終止的子進(jìn)程運(yùn)行時(shí),不要阻塞雷袋。
......
}
而不是使用會(huì)阻塞進(jìn)程的wait
函數(shù)吉殃。具體wait與waitpid
的對(duì)比,見UNP v3 5.10節(jié)
調(diào)用waitpid()出錯(cuò)返回-1后楷怒,檢查錯(cuò)誤信息蛋勺,如為EINTR
,說明waitpid
是被信號(hào)中斷進(jìn)而返回的鸠删。關(guān)于“中斷的系統(tǒng)調(diào)用”見APUE p260
.
pid == 0 說明當(dāng)前沒有子進(jìn)程終止抱完。
當(dāng)發(fā)現(xiàn)子進(jìn)程終止?fàn)顟B(tài)信息WEIXTSTATUS(status) = 2 時(shí),說明子進(jìn)程是在初始化過程中出錯(cuò)退出的冶共。
檢查源代碼發(fā)現(xiàn):ngx_worker_process_init
函數(shù)內(nèi)多處調(diào)用exit(2)
使子進(jìn)程退出乾蛤。而如果子進(jìn)程在進(jìn)程信息表中的標(biāo)志位respawn 為1,說明要求子進(jìn)程終止后應(yīng)重新拉起捅僵,但因?yàn)樽舆M(jìn)程退出是初始化過程出錯(cuò)導(dǎo)致的家卖,是無法重新拉起的,因?yàn)閷espawn清為0庙楚。
釋放子進(jìn)程worker占用的資源
未完待續(xù)上荡。。。酪捡。
作者:時(shí)光沖刷下的足跡
鏈接:
來源:簡(jiǎn)書
簡(jiǎn)書著作權(quán)歸作者所有叁征,任何形式的轉(zhuǎn)載都請(qǐng)聯(lián)系作者獲得授權(quán)并注明出處。