1. 產生原因:
在unix 系統中,乙個程序結束了,但是他的父程序沒有等待(呼叫wait / waitpid)他,那麼他將變成乙個殭屍程序。通過ps命令檢視其帶有defunct的標誌。殭屍程序是乙個早已死亡的程序,但在程序表 (processs table)中仍佔了乙個位置(slot)。
但是如果該程序的父程序已經先結束了,那麼該程序就不會變成殭屍程序。因為每個程序結束的時候,系統都會掃瞄當前系統中所執行的所有程序,看看有沒有哪個 程序是剛剛結束的這個程序的子程序,如果是的話,就由init程序來接管他,成為他的父程序,從而保證每個程序都會有乙個父程序。而init程序會自動 wait其子程序,因此被init接管的所有程序都不會變成殭屍程序。
2. 原理分析:
每個unix程序在程序表裡都有乙個進入點(entry),核心程序執 行該程序時使用到的一切資訊都儲存在進入點。當用 ps 命令察看系統中的程序資訊時,看到的就是程序表中的相關資料。當以fork()系統呼叫建立乙個新的程序後,核心程序就會在程序表中給這個新程序分配乙個 進入點,然後將相關資訊儲存在該進入點所對應的程序表內。這些資訊中有一項是其父程序的識別碼。
子程序的結束和父程序的執行是乙個非同步過程,即父程序永遠無法**子程序到底什麼時候結束。那麼會不會因為父程序太忙來不及 wait 子程序,或者說不知道子程序什麼時候結束,而丟失子程序結束時的狀態資訊呢?不會。因為unix提供了一種機制可以保證,只要父程序想知道子程序結束時的 狀態資訊,就可以得到。這種機制就是:當子程序走完了自己的生命週期後,它會執行exit()系統呼叫,核心釋放該程序所有的資源,包括開啟的檔案,占用 的記憶體等。但是仍然為其保留一定的資訊(包括程序號the process id,退出碼exit code,退出狀態the terminationstatus of the process,執行時間the amount of cpu time taken by the process等),這些資料會一直保留到系統將它傳遞給它的父程序為止,直到父程序通過wait / waitpid來取時才釋放。
3.解決方法:
(1) 父程序通過wait和waitpid等函式等待子程序結束,這會導致父程序掛起。
(2) 如果父程序很忙,那麼可以用signal函式為sigchld安裝handler。在子程序結束後,父程序會收到該訊號,可以在handler中呼叫wait**。
(3) 如果父程序不關心子程序什麼時候結束,那麼可以用signal(sigcld, sig_ign)或signal(sigchld, sig_ign)通知核心,自己對子程序的結束不感興趣,那麼子程序結束後,核心會**,並不再給父程序傳送訊號
(4)fork兩次,父程序fork乙個子程序,然後繼續工作,子程序fork乙個孫程序後退出,那麼孫程序被init接管,孫程序結束後,init會**。不過子程序的**還要自己做。
Linux下如何避免殭屍程序的產生
比如程序採用exit 退出的時候,作業系統會進行一些列的處理工作,包括關閉開啟的檔案描述符 占用的記憶體等等,但是,作業系統也會為該程序保留少量的資訊,比如程序id號等資訊,因而占用了系統的資源。在一種極端的情況下,檔殭屍程序過多的時候,占用了大量的程序id,系統將無法產生新的程序,相當於系統的資源...
Linux下殭屍程序的產生和解決方法
由下面一段cs架構的 說明下,殭屍程序的產生,下面是乙個簡單的回射伺服器,客戶端負責從標準輸入讀入資料,寫到服務端,服務端主程序監聽連線套接字,fork乙個子程序處理連線套接字,讀入資料和回寫給客戶端。大寫的函式只對出錯的情況進行處理。include include include include ...
mysql殭屍程序 殭屍程序產生原因和解決方法
在linux系統中,當用ps命令觀察程序的執行狀態時,經常看到某些程序的狀態列為defunct,這就是所謂的 殭屍 程序。殭屍 程序是乙個早已死亡的程序,但在程序表 processs table 中仍佔了乙個位置 slot 由於程序表的容量是有限的,所以,defunct程序不僅占用系統的記憶體資源,...