前言
最近接觸了殭屍進程這個概念,在被同學問到殭屍進程的產生、避免、危害時感覺還是概念模糊,沒有深入瞭解,現在做了一些整理來複習殭屍進程的相關知識。
殭屍進程是什麼?
在Linux下進程狀態由五種,僵死狀態就是一種特殊的進程狀態,它放棄了幾乎所有的內存地址空間,也沒有任何的可執行的代碼,也不被調度器再次調度,它僅僅是在進程列表中保留一個位置,在這個位置中記載了該進程的進程狀態。
Linux下的殭屍進程(Zombie) 和影視劇中的殭屍類似:殭屍進程就是處於僵死狀態的進程(進程已經退出,但資源並沒有完全被釋放)
。
殭屍進程是如何產生的?
子進程先於父進程退出
由於要保存自身的退出返回值,資源並沒有完全被釋放
此時操作系統通知父進程獲取子進程的退出狀態並允許操作系統釋放資源
但父進程默認忽略子進程退出時發送給父進程的SIGCHLD信號
所以父進程並沒有注意到子進程的退出狀態
導致子進程退出但資源並沒有完全被釋放處於僵死狀態導致了殭屍進程的出現
- 下面用代碼簡單的實現一下殭屍進程:
命令ps aux | grep -w ‘Z’ 可以看到進程3453是一個殭屍進程
注: 殭屍進程不能用 kill 命令殺死
簡單處理: 退出父進程,殭屍子進程變爲孤兒進程,由init進程收養釋放資源。
殭屍進程有哪些危害?
殭屍進程處於僵死狀態,資源並沒有完全被釋放(進程的ID號、進程的退出狀態、進程運行的CPU時間等)
可能會導致資源泄露的問題
並且由於操作系統所能創建的最大進程數量是有限的(進程號被大量佔用)會導致新的進程無法創建
殭屍進程該如何避免?
既然殭屍進程可能導致這麼嚴重的問題出現,那麼避免殭屍進程的出現就有着重要的意義,我們下面討論一下如何避免殭屍進程的出現。
- 方法一:進程等待
進程等待就是父進程調用wait/waitpid函數等待子進程的退出
獲取子進程的退出返回值並釋放子進程的資源
避免殭屍進程的出現
父進程創建子進程之後,子進程sleep5秒後退出,父進程sleep20秒再調用wait函數處理殭屍進程,這時子進程成爲15秒的殭屍進程後,進程等待獲取子進程的退出返回值,釋放子進程的資源。
- 方法二:處理SIGCHID信號
採用SIGCHLD信號通知處理機制
父進程註冊一個信號處理函數signal(SIGCHLD, sig_child)
然後每當子進程退出的時候父進程都會收到SIGCHLD信號
觸發sig_child函數,調用waitpid函數等待子進程的退出
運行結果:打斷父進程的阻塞 去處理SIGCHLD信號
小結
通過上面的學習,我們對殭屍進程的概念、產生、危害、避免都有了一定的認識,知己知彼才能百戰百勝,在今後的學習當中,在我們遇到殭屍進程帶來的問題時,我們就能很好的去處理這些麻煩了。