Linux系統僵死程序的處理
下面的程式碼,可以看到父程序執行10次,子程序執行3次。
我們將程式掛在後臺執行,當子程序執行結束後,我們執行ps檢視程序,可以看到,子程序好像仍然存在。
程序總歸是要終結的。當一個程序終結時,核心必須釋放它所佔有的資源,並把這一事件,告知其父程序。但是系統為了在子程序終結後仍能獲得它的資訊,所以程序保留了它的程序描述符(即PCB),所以這種情況的程序叫做僵死程序。
現在有以下方法可以處理僵死程序(可能不完整,我仍在補充)
方法一:父程序先於子程序退出。(可以但不實用)
我們更改程式程式碼,使父程序列印3次,子程序列印8次,子程序先於父程序退出。
可以看到,父程序和子程序都沒有進入僵死狀態,已經達到了基本目標。
所以我們只需要父程序先於子程序結束,如讓父程序執行時間短,先kill掉父程序,等等。
但是我們也發現了子程序的父程序(ppid)發生了變化,這種失去了原有父程序的子程序稱為孤兒程序。
如果父程序在子程序之前退出,必須有機制來保證子程序能找到一個新的父親,否則這些稱為孤兒的程序就會在退出時永遠處於僵死狀態,白白耗費記憶體。對於這個問題,解決方法是給子程序找一個程序當做父親,如果不行,就讓init做他們的父程序。這樣在子程序結束的時候,就不會稱為僵死程序。
但是很明顯這種方法太過強硬,有點殺雞取卵的味道,不是很好的解決方法。
方法二:呼叫wait()函式(無法達成併發執行)
我們在程式程式碼中直接加入wait()。
執行程式可以看到先執行了子程式,當子程式結束之後,父程式才開始執行。
wait()函式的標準動作是颳起呼叫它的程序,直到其中的一個子程序退出,此時函式會返回該子程序的PID。
這樣父程序就獲取了子程序的資訊,子程序就不會成為僵死程序,但是父程序會等待,無法達成併發。
方法三:獲取子程序的訊號。
獲取子程序結束後的訊號,並進行wait()處理。
執行結果如下圖:
可以看到在子程序結束了之後,並沒有產生僵死程序,因為我們對訊號進行了處理。