殭屍程序產生原因和解決方法

2022-05-07 02:12:07 字數 2038 閱讀 3310

在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

mysql殭屍程序 殭屍程序產生原因和解決方法

在linux系統中,當用ps命令觀察程序的執行狀態時,經常看到某些程序的狀態列為defunct,這就是所謂的 殭屍 程序。殭屍 程序是乙個早已死亡的程序,但在程序表 processs table 中仍佔了乙個位置 slot 由於程序表的容量是有限的,所以,defunct程序不僅占用系統的記憶體資源,...

Linux 殭屍程序產生原因及解決方法

linux 允許程序查詢核心以獲得其父程序的 pid,或者其任何子程序的執行狀態。例如,程序可以建立乙個子程序來執行特定的任務,然後呼叫諸如 wait 這樣的一些庫函式檢查子程序是否終止。如果子程序已經終止,那麼,它的終止代號將告訴父程序這個任務是否已成功地完成。為了遵循這些設計原則,不允許 lin...

Linux下殭屍程序的產生和解決方法

由下面一段cs架構的 說明下,殭屍程序的產生,下面是乙個簡單的回射伺服器,客戶端負責從標準輸入讀入資料,寫到服務端,服務端主程序監聽連線套接字,fork乙個子程序處理連線套接字,讀入資料和回寫給客戶端。大寫的函式只對出錯的情況進行處理。include include include include ...