僵尸線程產生原因?
僵尸進程的產生:
當一個進程創建了一個子進程時,他們的運行時異步的。即父進程無法預知子進程會在什么時候結束,那么如果父進程很繁忙來不及wait 子進程時,那么當子進程結束時,會不會丟失子進程的結束時的狀態信息呢?處于這種考慮unix提供了一種機制可以保證只要父進程想知道子進程結束時的信息,它就可以得到。
這種機制是:在每個進程退出的時候,內核釋放該進程所有的資源,包括打開的文件,占用的內存。但是仍然保留了一些信息(如進程號pid 退出狀態 運行時間等)。這些保留的信息直到進程通過調用wait/waitpid時才會釋放。這樣就導致了一個問題,如果沒有調用wait/waitpid的話,那么保留的信息就不會釋放。比如進程號就會被一直占用了。但系統所能使用的進程號的有限的,如果產生大量的僵尸進程,將導致系統沒有可用的進程號而導致系統不能創建進程。所以我們應該避免僵尸進程
這里有一個需要注意的地方。如果子進程先結束而父進程后結束,即子進程結束后,父進程還在繼續運行但是并未調用wait/waitpid那子進程就會成為僵尸進程。
但如果子進程后結束,即父進程先結束了,但沒有調用wait/waitpid來等待子進程的結束,此時子進程還在運行,父進程已經結束。那么并不會產生僵尸進程。應為每個進程結束時,系統都會掃描當前系統中運行的所有進程,看看有沒有哪個進程時剛剛結束的這個進程的子進程,如果有,就有init來接管它,成為它的父進程。
同樣的在產生僵尸進程的那種情況下,即子進程結束了但父進程還在繼續運行(并未調用wait/waitpid)這段期間,假如父進程異常終止了,那么該子進程就會自動被init接管。那么它就不再是僵尸進程了。應為intit會發現并釋放它所占有的資源。(當然如果進程表越大,init發現它接管僵尸進程這個過程就會變得越慢,所以在init為發現他們之前,僵尸進程依舊消耗著系統的資源)