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

2021-09-23 18:15:08 字數 3215 閱讀 9738

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

為了遵循這些設計原則,不允許 linux 核心在程序一終止後就丟棄包含在程序描述符欄位中的資料。只有父程序發出了與被終止的程序相關的 wait() 類系統呼叫之後,才允許這樣做。這就是引入僵死狀態的原因:儘管從技術上來說程序已死,但必須儲存它的描述符,直到父程序得到通知。

如果乙個程序已經終止,但是它的父程序尚未呼叫 wait() 或 waitpid() 對它進行清理,這時的程序狀態稱為僵死狀態,處於僵死狀態的程序稱為殭屍程序(zombie process)。任何程序在剛終止時都是殭屍程序,正常情況下,殭屍程序都立刻被父程序清理了。

殭屍程序是如何產生的

在unix 系統中,乙個程序結束了,但是他的父程序沒有等待(呼叫wait / waitpid)他,那麼他將變成乙個殭屍程序。通過ps命令檢視其帶有defunct的標誌。殭屍程序是乙個早已死亡的程序,但在程序表 (processs table)中仍佔了乙個位置(slot)。

但是如果該程序的父程序已經先結束了,那麼該程序就不會變成殭屍程序。因為每個程序結束的時候,系統都會掃瞄當前系統中所執行的所有程序,看看有沒有哪個 程序是剛剛結束的這個程序的子程序,如果是的話,就由init程序來接管他,成為他的父程序,從而保證每個程序都會有乙個父程序。而init程序會自動 wait其子程序,因此被init接管的所有程序都不會變成殭屍程序。

為了觀察到殭屍程序,我們自己寫乙個不正常的程式,父程序 fork 出子程序,子程序終止,而父程序既不終止也不呼叫 wait 清理子程序:?

#include

#include

#include

intmain(void)

if(pid > 0)

}

elseif(pid == 0)

return0;

}

把上面的**儲存到檔案 zomprocdemo.c 檔案中,並執行下面的命令編譯:?

$ gcc zomprocdemo.c -o zomprocdemo

然後執行編譯出來的 zomprocdemo 程式:?

此時子程序已經退出,但是父程序沒有退出也沒有通過 wait() 呼叫處理子程序。我們使用 ps 命令檢視程序的狀態:

上圖紅框中的大寫字母 "z" 說明 pid 為 112712 的程序此時處於僵死的狀態。

讓我們接著往下看!在結束 sleep 後父程序退出。當父程序退出後,子程序會變成孤兒程序,此時它會被乙個管理程序收養。在不同的系統中,這個管理程序不太一樣,早期一般是 init 程序,ubuntu 上是 upstart,還有近來的 systemd。但是它們都完成相同的任務,就是 wiat() 這些孤兒程序,並最終釋放它們占用的系統程序表中的資源。這樣,這些已經僵死的孤兒程序就徹底的被清除了。

殭屍程序的危害

在程序退出的時候,核心釋放該程序所有的資源,包括開啟的檔案,占用的記憶體等。但是仍然為其保留一定的資訊(包括程序號 pid,退出狀態 the termination status of the process,執行時間 the amount of cpu time taken by the process 等)。直到父程序通過 wait / waitpid 來取時才釋放。

如果程序不呼叫 wait / waitpid 的話, 那麼保留的那段資訊就不會釋放,其程序號就會一直被占用,但是系統所能使用的程序號是有限的,如果大量的產生僵死程序,將因為沒有可用的程序號而導致系統不能產生新的程序。

如何處理殭屍程序

殭屍程序的產生是因為父程序沒有 wait() 子程序。所以如果我們自己寫程式的話一定要在父程序中通過 wait() 來避免殭屍程序的產生。

當系統**現了殭屍程序時,我們是無法通過 kill 命令把它清除掉的。但是我們可以殺死它的父程序,讓它變成孤兒程序,並進一步被系統中管理孤兒程序的程序收養並清理。

下面的 demo 中,父程序通過 wait() 等待子程序結束:?

#include

#include

#include

#include

#include

intmain(void)

if(pid == 0)

// exit with code 3 for test.

exit(3);

}

else

}

return0;

}

demo 中父程序不僅等待子程序結束,還通過 wexitstatus 巨集取到了子程序的 exit code。

殭屍程序的產生原因

在linux系統中,殭屍程序是已經執行完畢,但是沒有被父程序 的子程序。判斷殭屍程序的乙個方法是使用ps命令檢視程序狀態。如果程序狀態是z,說明這是乙個殭屍程序。在多程序的程式中,父程序會啟動若干個子程序來處理任務。當子程序退出後,除了在程序表中占用的乙個程序表項,子程序所使用的資源 檔案描述符 記...

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

1.產生原因 在unix 系統中,乙個程序結束了,但是他的父程序沒有等待 呼叫wait waitpid 他,那麼他將變成乙個殭屍程序。通過ps命令檢視其帶有defunct的標誌。殭屍程序是乙個早已死亡的程序,但在程序表 processs table 中仍佔了乙個位置 slot 但是如果該程序的父程序...

Linux系統中殭屍程序的產生原因及kill方法

在linux系統中,當用ps命令觀察程序的執行狀態時,可以看到某些程序的狀態列為defunct,這就是所謂的 殭屍 程序 一 如何檢視殭屍程序 使用ps ef grep z 命令 或者使用top命令 二 殭屍程序的產生原因 linux系統在程序表裡都有乙個進入點 entry 核心程式執行該程序時使用...