在linux系統中,當用ps命令觀察程序的執行狀態時,經常看到某些程序的狀態列為defunct,這就是所謂的「殭屍」程序。「殭屍」程序是乙個早已死亡的程序,但在程序表(processs table)中仍佔了乙個位置(slot)。由於程序表的容量是有限的,所以,defunct程序不僅占用系統的記憶體資源,影響系統的效能,而且如果其數目太多,還會導致系統癱瘓。
我們可以使用top命令直接檢視殭屍程序個數:
一、殭屍程序的產生原因
我們知道,每個程序在程序表裡都有乙個進入點(entry),核心程式執行該程序時使用到的一切資訊都儲存在進入點。當用ps命令察看系統中的程序資訊時,看到的就是程序表中的相關資料。
所以,當乙個父程序以fork()系統呼叫建立乙個新的子程序後,核心程序就會在程序表中給這個子程序分配乙個進入點,然後將相關資訊儲存在該進入點所對應的程序表內。這些資訊中有一項是其父程序的識別碼。
而當這個子程序結束的時候(比如呼叫exit命令結束),其實他並沒有真正的被銷毀,而是留下乙個稱為殭屍程序(zombie)的資料結構(系統呼叫exit的作用是使程序退出,但是也僅僅限於乙個正常的程序變成了乙個殭屍程序,並不能完全將其銷毀)。
此時原來程序表中的資料會被該程序的退出碼(exit code)、執行時所用的cpu時間等資料所取代,這些資料會一直保留到系統將它傳遞給它的父程序為止。由此可見,defunct程序的出現時間是在子程序終止後,但是父程序尚未讀取這些資料之前。
此時,該殭屍子程序已經放棄了幾乎所有的記憶體空間,沒有任何可執行**,也不能被排程,僅僅在程序列表中保留乙個位置,記載該程序的退出狀態資訊供其他程序收集,除此之外,殭屍程序不再占有任何儲存空間。他需要他的父程序來為他收屍,如果他的父程序沒有安裝sigchld訊號處理函式呼叫wait 或 waitpid() 等待子程序結束,也沒有顯式忽略該訊號,那麼它就一直保持殭屍狀態,如果這時候父程序結束了,那麼init程序會自動接手這個子程序,為他收屍,他還是能被清除掉的。但是如果父程序是乙個迴圈,不會結束,那麼子程序就會一直保持殭屍狀態,這就是系統中為什麼有時候會有很多的殭屍程序。
簡單解釋就是:
當你執行乙個程式時,它會產生乙個父程序以及很多子程序。 所有這些子程序都會消耗核心分配給它們的記憶體和 cpu 資源。
這些子程序完成執行後會傳送乙個 exit 訊號然後死掉。這個 exit 訊號需要被父程序所讀取。父程序需要隨後呼叫 wait 命令來讀取子程序的退出狀態,並將子程序從程序表中移除。
若父程序正確第讀取了子程序的 exit 訊號,則子程序會從程序表中刪掉。
但若父程序未能讀取到子程序的 exit 訊號,則這個子程序雖然完成執行處於死亡的狀態,但也不會從程序表中刪掉。
二、殭屍程序對系統有害嗎?
不會。由於殭屍程序並不做任何事情, 不會使用任何資源也不會影響其它程序, 因此存在殭屍程序也沒什麼壞處。
不過由於程序表中的退出狀態以及其它一些程序資訊也是儲存在記憶體中的,因此存在太多殭屍程序有時也會是一些問題。
三、如何殺死殭屍程序
如上可知,殭屍程序一旦出現之後,很難自己消亡,會一直存在下去,直至系統重啟。雖然殭屍程序幾乎不佔系統資源,但是,這樣下去,數量太多了之後,終究會給系統帶來其他的影響。因此,如果一旦見到殭屍程序,我們就要將其殺掉。如何殺掉殭屍程序呢?
有同學可能會說,很簡單嘛,直接使用kill命令就好啊。或者,實在不行,加乙個-9的字尾(kill -9),肯定殺掉!
請注意:defunct狀態下的殭屍程序是不能直接使用kill -9命令殺掉的,否則就不叫殭屍程序了。那麼,該如何殺呢?
方法:重啟伺服器電腦,這個是最簡單,最易用的方法,但是如果你伺服器電腦上執行有其他的程式,那麼這個方法,代價很大。所以,盡量使用下面一種方法。
找到該defunct殭屍程序的父程序,將該程序的父程序殺掉,則此defunct程序將自動消失。
問題又來了,如何找到defunct殭屍程序的父程序呢?
ps -ef | grep defunct_process_pid
防止殭屍程序的產生
apue的 直接貼這裡。這段 採用了兩次fork,來避免產生殭屍程序。當乙個程序的父程序先退出,該程序就由init程序接管。init程序就成為了該程序的父程序 該程序退出時,有init來清理。所以該程序就不會成為殭屍程序了。include include include include intmai...
殭屍程序的產生原因
在linux系統中,殭屍程序是已經執行完畢,但是沒有被父程序 的子程序。判斷殭屍程序的乙個方法是使用ps命令檢視程序狀態。如果程序狀態是z,說明這是乙個殭屍程序。在多程序的程式中,父程序會啟動若干個子程序來處理任務。當子程序退出後,除了在程序表中占用的乙個程序表項,子程序所使用的資源 檔案描述符 記...
殭屍程序和如何刪除殭屍程序
當乙個子程序結束後,他的父程序沒有等待他 wait waitpid 清除他的所有資源時,它就變成乙個殭屍程序。在linux系統中,在每個程序退出的時候,核心釋放該程序所有的資源,包括開啟的檔案,占用的記憶體等。但是仍然為其保留一定的資訊 包括程序號the process id,退出狀態the ter...