在 unix / linux 中,正常情況下,子程序是通過父程序建立的,子程序再建立新的程序。子程序的結束和父程序的執行是乙個非同步過程,即父程序永遠無法**子程序到底什麼時候結束。 當乙個程序完成它的工作終止之後,它的父程序需要呼叫 wait() 或者 waitpid() 系統呼叫取得子程序的終止狀態。
任何乙個子程序(init除外)在exit()之後,並非馬上就消失掉,而是留下乙個稱為殭屍程序(zombie)的資料結構,等待父程序處理。這是每個子程序在結束時都要經過的階段。如果子程序在exit()之後,父程序沒有來得及處理,這時用ps命令就能看到子程序的狀態是「z」。如果父程序能及時處理,可能用ps命令就來不及看到子程序的殭屍狀態,但這並不等於子程序不經過殭屍狀態。 如果父程序在子程序結束之前退出,則子程序將由 init 接管。init 將會以父程序的身份對殭屍狀態的子程序進行處理。
乙個父程序退出,而它的乙個或多個子程序還在執行,那麼那些子程序將成為孤兒程序。孤兒程序將被init程序(程序號為 1)所收養,並由 init 程序對它們完成狀態收集工作。由於孤兒程序會被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 時就可以得到這些資訊。
乙個程序如果只 fork 子程序而不負責對子程序進行 wait() 或是 waitpid() 呼叫來釋放其所占有資源的話,那麼就會產生很多的僵死程序。保留的那段資訊不會釋放,其程序號會一直被占用,但是系統所能使用的程序號是有限的,如果大量的產生僵死程序,將因為沒有可用的程序號而導致系統不能產生新的程序。
孤兒程序是子程序還在執行,而父程序掛了,子程序被 init 程序收養。殭屍程序是父程序還在執行但是子程序掛了,但是父程序卻沒有使用 wait 來清理子程序的程序資訊,導致子程序雖然執行實體已經消失,但是仍然在核心的程序表中佔據一條記錄,這樣長期下去對於系統資源是乙個浪費。殭屍程序將會導致資源浪費,而孤兒程序則不會。
父程序通過 wait 和 waitpid 等函式等待子程序結束,這會導致父程序掛起。
如果父程序很忙,那麼可以用 signal 函式為 sigchld 安裝 handler。在子程序結束後,父程序會收到該訊號,可以在handler中呼叫wait**。
如果父程序不關心子程序什麼時候結束,那麼可以用signal(sigcld, sig_ign)或signal(sigchld, sig_ign)通知核心,自己對子程序的結束不感興趣,那麼子程序結束後,核心會**,並不再給父程序傳送訊號。
fork兩次,父程序fork乙個子程序,然後繼續工作,子程序fork乙個孫程序後退出,那麼孫程序被init接管,孫程序結束後,init會**。不過子程序的**還要自己做。
將其父程序殺死,此時所有的僵死程序就會程式設計孤兒程序,從而被 init 所收養,這樣 init 就會釋放所有的僵死程序所占有的資源,從而結束僵死程序。
Linux 殭屍程序與孤兒程序
之前的部落格有講過儲存程序資訊的乙個重要的資料結構,task struct結構體,其中,state表示程序可能出現的狀態。如下 static const char const task state array 我們對個別狀態進行解釋如下 s sleeping 淺度睡眠,也是不可中斷睡眠。d disk...
Linux 殭屍程序與孤兒程序
產生原因 子程序先於父程序退出,他要保留退出原因在pcb中,因此退出後不會自動釋放所有資源,子程序退出後作業系統會通知父程序,子程序退出了,去獲取一下原因,然後完全釋放子程序資源,假如父程序不管子程序的退出狀態,那麼這個子程序將進入僵死狀態,成為殭屍程序 實現殭屍程序 該程式為20秒的殭屍程序,在第...
Linux 殭屍程序與孤兒程序
殭屍程序 產生原因 子程序先於父程序退出,他要保留退出原因在pcb中,因此退出後不會自動釋放所有資源,子程序退出後作業系統會通知父程序,子程序退出了,去獲取一下原因,然後完全釋放子程序資源,假如父程序不管子程序的退出狀態,那麼這個子程序將進入僵死狀態,成為殭屍程序 實現殭屍程序 該程式為20秒的殭屍...