一、前言
什麼是孤兒進程和殭屍進程,會帶來什麼問題,怎麼解決?
二、基本概念
咱們知道在unix/linux中,正常狀況下,子進程是經過父進程建立的,子進程在建立新的進程。子進程的結束和父進程的運行是一個異步過程,即父進程永遠沒法預測子進程到底何時結束。 當一個進程完成它的工做終止以後,它的父進程須要調用wait()或者waitpid()系統調用取得子進程的終止狀態。
孤兒進程:一個父進程退出,而它的一個或多個子進程還在運行,那麼那些子進程將成爲孤兒進程。孤兒進程將被init進程(進程號爲1)所收養,並由init進程對它們完成狀態收集工做。
殭屍進程:一個進程使用fork建立子進程,若是子進程退出,而父進程並無調用wait或waitpid獲取子進程的狀態信息,那麼子進程的進程描述符仍然保存在系統中。這種進程稱之爲僵死進程。
三、問題及危害
unix提供了一種機制能夠保證只要父進程想知道子進程結束時的狀態信息, 就能夠獲得。這種機制就是: 在每一個進程退出的時候,內核釋放該進程全部的資源,包括打開的文件,佔用的內存等。 可是仍然爲其保留必定的信息(包括進程號the process ID,退出狀態the termination status of the process,運行時間the amount of CPU time taken by the process等)。直到父進程經過wait / waitpid來取時才釋放。但這樣就致使了問題,若是進程不調用wait /waitpid的話, 那麼保留的那段信息就不會釋放,其進程號就會一直被佔用,可是系統所能使用的進程號是有限的,若是大量的產生僵死進程,將由於沒有可用的進程號而致使系統不能產生新的進程. 此即爲殭屍進程的危害,應當避免。孤兒進程是沒有父進程的進程,孤兒進程這個重任就落到了init進程身上,每當出現一個孤兒進程的時候,內核就把孤兒進程的父進程設置爲init,而init進程會循環地wait()它的已經退出的子進程。所以孤兒進程並不會有什麼危害。
任何一個子進程(init除外)在exit()以後,並不是立刻就消失掉,而是留下一個稱爲殭屍進程(Zombie)的數據結構,等待父進程處理。這是每一個子進程在結束時都要通過的階段。若是子進程在exit()以後,父進程沒有來得及處理,這時用ps命令就能看到子進程的狀態是「Z」。若是父進程能及時處理,可能用ps命令就來不及看到子進程的殭屍狀態,但這並不等於子進程不通過殭屍狀態。若是父進程在子進程結束以前退出,則子進程將由init接管。init將會以父進程的身份對殭屍狀態的子進程進行處理。linux