僵尸進程并不可怕账劲,可怕的是量大瀑焦。僵尸進程是有它存在的意義的梗肝。以下解釋摘自百度百科:
由于子進程的結(jié)束和父進程的運行是一個異步過程,即父進程永遠無法預測子進程 到底什么時候結(jié)束. 那么會不會因為父進程太忙來不及wait子進程巫击,或者說不知道 子進程什么時候結(jié)束,而丟失子進程結(jié)束時的狀態(tài)信息呢? 不會粹懒。因為UNⅨ提供了一種機制可以保證只要父進程想知道子進程結(jié)束時的狀態(tài)信息顷级, 就可以得到。這種機制就是: 在每個進程退出的時候,內(nèi)核釋
放該進程所有的資源删掀,包括打開的文件嚣镜,占用的內(nèi)存等。但是仍然為其保留一定的信息(包括進程號the process ID菊匿,退出狀態(tài)the
termination status of the process跌捆,運行時間the amount of CPU time taken by
the process等)。直到父進程通過wait / waitpid來取時才釋放. 但這樣就導致了問題姆钉,如果進程不調(diào)用wait / waitpid的話抄瓦,那么保留的那段信息就不會釋放,其進程號就會一直被占用钙姊,但是系統(tǒng)所能使用的進程號是有限的煞额,如果大量的產(chǎn)生僵死進程,將因為沒有可用的進程號而導致系統(tǒng)不能產(chǎn)生新的進程. 此即為僵尸進程的危害胀莹,應(yīng)當避免。
僵尸進程的避免:
⒈父進程通過wait和waitpid等函數(shù)等待子進程結(jié)束描焰,這會導致父進程掛起栈顷。
⒉ 如果父進程很忙嵌巷,那么可以用signal函數(shù)為SIGCHLD安裝handler,因為子進程結(jié)束后靡努, 父進程會收到該信號,可以在handler中調(diào)用wait回收兽泄。
⒊ 如果父進程不關(guān)心子進程什么時候結(jié)束漾月,那么可以用signal(SIGCHLD,SIG_IGN) 通知內(nèi)核,自己對子進程的結(jié)束不感興趣蜓陌,那么子進程結(jié)束后吩蔑,內(nèi)核會回收, 并不再給父進程發(fā)送信號隧期。
⒋ 還有一些技巧赘娄,就是fork兩次,父進程fork一個子進程性置,然后繼續(xù)工作暑诸,子進程fork一 個孫進程后退出辟灰,那么孫進程被init接管,孫進程結(jié)束后西采,init會回收继控。不過子進程的回收 還要自己做。