殭屍程序就是已經結束的程序(幾乎不佔計算機資源),但是它並沒有從程序列表中刪除。殭屍程序太多會導致作業系統的程序數目過多,從而佔滿了os的程序表。進而導致無法建立新程序,致使os崩潰。
殭屍程序幾乎不佔資源,它沒有可執行**,也不能被排程,但是它佔據著程序表中的乙個位置,記載這該程序的pcb資訊。它需要等待他的父程序來終結它。一旦它的父程序是乙個迴圈,不會結束(父程序不去呼叫wait函式或者waitpid函式)。那麼子程序將會一直保持殭屍狀態。那麼它將一直占用程序號,系統就沒法**利用。
在linux下使用top命令可以產看當前程序數目,以及程序的狀態。例如:
可以看到我的系統暫時並沒有殭屍程序(zombie) 。掛起的程序倒是一大堆。
殭屍程序產生的原因:每個linux程序在程序表中都有乙個進入點,核心執行該程序時,使用到的一切資訊都存入在程序點。我們可以使用ps命令來檢視程序狀態。當乙個父程序以fork()系統呼叫建立乙個新的子程序後,核心程序就會在程序表中給這個子程序分配乙個進入點,然後將相關資訊儲存在該進入點所對應的程序表內。這些資訊中有一項是其父程序的識別碼。而當這個子程序結束的時候(呼叫exit命令結束),其實他並沒有真正的被銷毀,而是留下乙個殭屍程序的。此時原來程序表中的資料會被該程序的退出碼(exit code)、執行時所用的cpu時間等資料所取代,這些資料會一直保留到系統將它傳遞給它的父程序為止。
我們用下面的**來產生殭屍程序
#include#include#includeint main()
sleep(1);
}return 0;
}
執行結果如下:
會一直在終端上列印當前目錄下的檔案。同時我們另開乙個終端,輸入top命令,將會看到zombie程序的數量在一直增長。如下圖所示:
如何避免殭屍程序:
可以在父程序中通過呼叫wait()和waitpid函式等待子程序結束,但是這會導致父程序掛起。
父程序不能掛起,父程序要做的工作很多,很忙。那麼可以使用signal函式為sigchld安裝handler,因為子程序結束後,父程序會收到該訊號,可以在headler中使用wait函式來**子程序。
如果父程序不關心子程序什麼時候結束(比如fork後使用了execl函式啟動了另外乙個可執行程式),那麼可以使用single(sigchld,sig_ign)通知核心來**子程序。
fork兩次,首先父程序fork乙個子程序,然後繼續工作,子程序fork乙個孫子程序後退出,那麼孫子程序將會變成孤兒程序(因為他父親死了,這就是孤兒),從而被init程序接管。但是子程序的**仍舊需要父程序來做,好處是不用使用wait()來掛起了,父程序可以忙自己的。
使用wait函式和waitpid函式。
wait函式:需要標頭檔案#include
函式原型:pid_t wait(int *status);
函式功能:阻塞(睡眠)程序,等待子程序結束,負責為子程序**資源。引數是接受的子程序退出狀態,返回值是子程序的pid,出錯為-1。
我們主要使用兩個巨集來提取status裡儲存的子程序的退出資訊。
wexitstatus(status);//從status中提取出子程序是否正常退出,若正常退出,返回非0值。
wexitstatus(status);//經過上乙個巨集判斷後,使用該巨集取出程序結束時候的結束碼。
#include#include#include#include#includeint main()
if(0 < pid1)
return 0;
}
執行結果如下:
waitpid函式和wait的不同之處在於,waitpid函式多了兩個引數,使我們能控制等待的程序,以及是否等待。
函式原型:pid_t waitpid(pid_t pid, int *status, int options);
函式功能:pid是控制等待的程序,status和wait中的意義一樣,options引數一般用了控制父程序是否等待。
pid = -1 :等待任何子程序,相當於wait函式。
pid = 0:等待同乙個程序組中的任何子程序(如果子程序已經加入了別的程序組,waitpid 不會等待它)。
pid > 0:等待任何子程序識別碼為pid的子程序
pid < -1:等待程序組識別碼為pid絕對值的任何子程序options:它的取值組合由系統預定義的。可以為0和一些巨集的或。當他為0時,和wait()一樣,阻塞父程序,等待子程序退出。當他取值為wnohang時,如果沒有已經結束的子程序則馬上返回,不等待子程序。最常用的就是這兩個。
將上面**中的
pid2 = wait(&statu);
替換為下面這句**
pid2 = waitpid(pid1,&statu,wnohang);
執行結果將會發生變化:
顯而易見,父程序沒有等待子程序,直接執行,列印父程序中**,由於未初始化statu的緣故,列印乙個隨機值。m是從statu中提取出來的,也是隨機值。設定了選項 wnohang,而呼叫中 waitpid() 發現沒有已退出的子程序可等待,返回0。所以取到的子程序的pid是0。
Linux 殭屍程序
怎樣產生殭屍程序的 乙個程序在呼叫exit命令結束自己的生命的時候,其實它並沒有真正的被銷毀,而是留下乙個稱為殭屍程序 zombie 的資料結構 系統呼叫 exit,它的作用是使程序退出,但也僅僅限於將乙個正常的程序變成乙個殭屍程序,並不能將其完全銷毀 在linux程序的狀態中,殭屍程序是非常特殊的...
linux殭屍程序
僵死程序 在unix程序模型中,程序是按照父程序產生子程序,子程序產生子子程序這樣的方式建立出完成各項相互協作功能的程序的。當乙個程序完成它的工作終止之後,它的父程序需要呼叫wait 或者waitpid 系統呼叫取得子程序的終止狀態。如果父程序沒有這麼做的話,子程序雖然已經退出了,但是在系統程序表中...
linux殭屍程序
殭屍程序是指子程序退出時,父程序並未對其發出的sigchild訊號進行適當處理,導致子程序停留在殭屍狀態等待其父程序為其收屍,這個狀態下的子程序就是殭屍程序。include include include int main int argc,char argv return 0 從上面的執行結果可以...