標籤:
由於子進程的結束和父進程的運行是一個非同步過程,即父進程永遠無法預測子進程到底什麼時候結束. 那麼會不會因為父進程太忙來不及wait子進程,或者說不知道子進程什麼時候結束,而丟失子進程結束時的狀態資訊呢? 不會。因為UNIX提供了一種機制可以保證只要父進程想知道子進程結束時的狀態資訊,就可以得到。這種機制就是: 在每個進程退出的時候,核心釋放該進程所有的資源,包括開啟的檔案,佔用的記憶體等。 但是仍然為其保留一定的資訊(包括進程號、退出狀態、已耗用時間等)。直到父進程通過wait / waitpid來取時才釋放. 但這樣就導致了問題,如果進程不調用wait/waitpid的話, 那麼保留的那段資訊就不會釋放,其進程號就會一直被佔用,但是系統所能使用的進程號是有限的,如果大量的產生僵死進程,將因為沒有可用的進程號而導致系統不能產生新的進程. 此即為殭屍進程的危害,應當避免。
殭屍進程包括的資源:例如進程的ID號、進程的退出狀態、進程啟動並執行CPU時間等。因此進程在終止時,回收所有核心分配給它的記憶體、關閉它開啟的所有檔案等等,但是還會保留以上極少的資訊,以供父進程使用。父進程可以使用 wait/waitpid 等系統調用來為子進程收拾,做一些收尾工作。
如果某個進程自身終止了,在調用exit清理完相關的內容檔案等資源後,它就會進入ZOMBIE狀態,它的父進程會調用wait4來回收這個task_struct,但是,如果父進程一直沒有調用wait4去釋放子進程的task_struct,問題就來了,這個task_struct誰來回收呢?永遠沒有人,除非父進程終止後,被init進程接管這個ZOMBIE進程,然後調用wait4來回收進程描述符。如果父進程一直在運行著,這個ZOMBIE會永遠的佔用系統資源,用KILL發任何訊號量也不能釋放它。這是很可怕的,因為伺服器上可能會出現無數ZOMBIE進程導致機器掛掉。
其實就是進程描述符沒有被收回task_struct,也叫做進程表項
linux殭屍進程