Linux 殭屍程序與孤兒程序

2021-07-30 18:09:02 字數 3088 閱讀 5561



之前的部落格有講過儲存程序資訊的乙個重要的資料結構,task_struct結構體,其中,state表示程序可能出現的狀態。如下:

static const char * const task_ state _

array=

我們對個別狀態進行解釋如下:

s(sleeping) ——淺度睡眠,也是不可中斷睡眠。

d(disk sleep)——也是一種sleep狀態,是深度睡眠,也是可中斷睡眠。正常情況下,只要該程序處於d狀態,誰都不能操作它了,除非是程序自己想退出這種狀態了才能退出,可謂刀槍不入。這種狀態在i/o中出現居多,例如某程序在向硬碟請求讀資料時,在等待期間,該程序就應處於d狀態。不然在等待期間該程序被外界強行結束了,那麼從硬碟讀取出的資料將無處安放,為避免此情況發生,就應將此時的程序設為d狀態,讓外界無法操作、刀槍不入。

z(zombie) ——殭屍狀態

我們把子程序退出一直到父程序過來檢驗子程序的這段時間的狀態叫做殭屍狀態。

由於子程序的結束和父程序的執行是乙個非同步過程,即父程序永遠無法**子程序到底什麼時候結束. 那麼會不會因為父程序太忙來不及wait子程序,或者說不知道子程序什麼時候結束,而丟失子程序結束時的狀態資訊(

包括:退出的原因、是否異常退出、有無做完自身工作等等)呢?

當然不會。因為linux提供了一種機制可以保證只要父程序想知道子程序結束時的狀態資訊, 就可以得到。這種機制就是: 在每個程序退出的時候,核心只先釋放該程序所有的資源,包括開啟的檔案,占用的記憶體等。但pcb並不會被立即釋放,因為pcb儲存著子程序退出時的狀態資訊,直到父程序通過wait / waitpid來取子程序的狀態資訊時,才釋放pcb.

但這樣就導致了問題,如果父程序一直不呼叫wait / waitpid的話,那麼保留子程序狀態資訊的pcb就不會釋放,此子程序的程序號就會一直被占用,但是系統所能使用的程序號是有限的,如果大量的產生僵死程序,將因為沒有可用的程序號而導致系統不能產生新的程序. 此即為殭屍程序的危害,應當避免。

讓我們看乙個殭屍程序的例子:

1>用makefile生成乙個可執行檔案jiangshi ,執行./jiangshi (呵呵~~忽略渣渣命名)

殭屍程序的**jiangshi.c如下:

#include#include#includeint main()

else if( id > 0 )

}else

return 0;

}

其執行結果如下:

恩,跟我們預想的一樣,子程序建立成功後,父程序和子程序一起執行3s,3s後子程序結束,父程序並未結束而是繼續執行,那麼這個時候子程序就變成殭屍程序了。下面我們來驗證一下。

2>再開啟乙個命令列(terminal),輸入指令ps -al觀察此時程序的狀態

可以知道:

①子程序變成了殭屍程序,不僅其狀態位變成了z(

zombie

) ,而且子程序後還跟了乙個,表示該程序已死亡,已廢止  。

②如果這個殭屍程序一直得不到父程序

通過wait / waitpid來取它的狀態資訊,那麼它就會乙隻占用著這個4207(pid)的程序號。如果產生大量

僵死程序,就會

因為沒有可用的程序號而導致系統不能產生新的程序

, 所以應當避免殭屍程序。

下面,我們在講第二個重要的程序,孤兒程序。

孤兒程序

乙個父程序結束,而它的子程序還在執行,那麼那些還在執行的子程序將成為孤兒程序,孤兒程序將被init程序(程序號為1的程序)所收養,並由init程序對它們完成狀態收集工作。

說明:①由之前殭屍程序的知識我們可以知道,父程序結束後也會變成殭屍程序,由子程序的「爺爺程序」

通過wait / waitpid來取父程序的狀態資訊,而這裡的

「爺爺程序」其實就是bash。

②那麼也一樣,孤兒程序結束後,會由領養它的

init程序

通過wait / waitpid來取孤兒程序的狀態資訊 。

讓我們看乙個孤兒程序的例子:

1>用makefile生成乙個可執行檔案myfile,執行./myfile

孤兒程序的**myfile.c如下:

#include#include#includeint main()

}else if( id > 0 )

else

return 0;

}

其執行結果如下:

我們可以看到,跟預想的一樣,子程序建立成功後,父程序和子程序一起執行3s,3s後 父程序結束,子程序並未結束而是繼續執行,那麼子程序就成了孤兒程序。我們用下面的方法進行驗證。

2>跟殭屍程序驗證方法一樣,再開啟乙個命令列(terminal),輸入指令ps -al觀察此時程序的狀態

我們會發現兩點:

①孤兒程序確實被init程序(程序號為1的程序)所收養。 ②

沒有顯示變成殭屍程序的父程序,說明

父程序被

子程序的「爺爺程序」bash,

通過wait / waitpid來取走狀態資訊後釋放了。

由於我也是剛剛接觸linux,知識儲備還很不足,文中可能會有錯誤,如果出現錯誤的話,請務必告訴我~~~~ 

Linux 殭屍程序與孤兒程序

產生原因 子程序先於父程序退出,他要保留退出原因在pcb中,因此退出後不會自動釋放所有資源,子程序退出後作業系統會通知父程序,子程序退出了,去獲取一下原因,然後完全釋放子程序資源,假如父程序不管子程序的退出狀態,那麼這個子程序將進入僵死狀態,成為殭屍程序 實現殭屍程序 該程式為20秒的殭屍程序,在第...

Linux 殭屍程序與孤兒程序

殭屍程序 產生原因 子程序先於父程序退出,他要保留退出原因在pcb中,因此退出後不會自動釋放所有資源,子程序退出後作業系統會通知父程序,子程序退出了,去獲取一下原因,然後完全釋放子程序資源,假如父程序不管子程序的退出狀態,那麼這個子程序將進入僵死狀態,成為殭屍程序 實現殭屍程序 該程式為20秒的殭屍...

Linux 殭屍程序與孤兒程序

殭屍程序 乙個程序使用 fork 建立子程序,如果子程序退出而父程序並沒有呼叫 wait 或者 waitpid 獲取子程序資訊,那麼子程序的描述符仍然儲存在系統中。這種程序就被稱為殭屍程序 即 z 程序 危害及解決辦法 乙個程序會定期的產生一些子程序,這些子程序由於處理的事情很少並且處理完後會退出,...