天天看點

linux下孤兒程序和僵屍程序

我們知道在linux中,正常情況下,子程序是通過父程序建立的,子程序在建立新的程序。子程序的結束和父程序的運作是一個異步過程,即父程序永遠無法預測子程序 到底什麼時候結束。 當一個 程序完成它的工作終止之後,它的父程序需要調用wait()或者waitpid()系統調用取得子程序的終止狀态。

孤兒程序:一個父程序退出,而它的一個或多個子程序還在運作,那麼那些子程序将成為孤兒程序。孤兒程序将被init程序(程序号為1)所收養,并由init程序對它們完成狀态收集工作。

僵屍程序:一個程序使用fork建立子程序,如果子程序退出,而父程序并沒有調用wait或waitpid擷取子程序的狀态資訊,那麼子程序的程序描述符仍然儲存在系統中。這種程序稱之為僵死程序。

  

Linux提供了一種機制可以保證隻要父程序想知道子程序結束時的狀态資訊, 就可以得到。這種機制就是: 在每個程序退出的時候,核心釋放該程序所有的資源,包括打開的檔案,占用的記憶體等。 但是仍然為其保留一定的資訊(包括程序号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,而init程序會循環地wait()它的已經退出的子程序。這樣,當一個孤兒程序凄涼地結束了其生命周期的時候,init程序就會代表黨和政府出面處理它的一切善後工作。是以孤兒程序并不會有什麼危害。

任何一個子程序(init除外)在exit()之後,并非馬上就消失掉,而是留下一個稱為僵屍程序(Zombie)的資料結構,等待父程序處理。這是每個 子程序在結束時都要經過的階段。如果子程序在exit()之後,父程序沒有來得及處理,這時用ps指令就能看到子程序的狀态是“Z”。如果父程序能及時 處理,可能用ps指令就來不及看到子程序的僵屍狀态,但這并不等于子程序不經過僵屍狀态。 如果父程序在子程序結束之前退出,則子程序将由init接管。init将會以父程序的身份對僵屍狀态的子程序進行處理。

 

下面測試一下孤兒程序:

linux下孤兒程式和僵屍程式

結果為:

linux下孤兒程式和僵屍程式

這個時候我們發現子程序在付程序推出後就變為交給了程序1也就是init程序來托管了;

下面測試僵屍程序:

linux下孤兒程式和僵屍程式

結果為:

linux下孤兒程式和僵屍程式

我們發現子程序的狀态變為了Z,代表其成了一個僵屍程序,因為其父親是一個死循環,而子程序在退出之後,其父程序并沒有回收它,是以它作為一個僵屍程序會一直停留在記憶體中,占據記憶體;如果僵屍程序多了的話,那麼對于記憶體而言,就是極大的危害;

繼續閱讀