當乙個程序終止時,作業系統會釋放其資源,不過它位於程序表中的條目還是在的,直到它的父程序呼叫wait();這是因為程序表中包含了程序的退出狀態。當程序已經終止,但是其父進尚未呼叫wait(),這樣的程序叫做殭屍程序(zombie prpcess)。
所有程序終止時都會過度到這種狀態,但是一般而言殭屍只是短暫存在。一旦父程序呼叫了wait(),殭屍程序的程序標示符和它在程序表中的條目就會釋放。
這裡需要注意:殭屍程序不能通過kill來進行殺死,因為kill是用來終止程序的,殭屍程序已經是終止的。
設計乙個殭屍程序:
#include
#include
#include
#include
#include
#include
#include
#include
//殭屍程序
intmain
(void
)else
if(pid ==0)
else
printf
("fork after ... \n");
}
執行結果:
shanlei@shanlei-lenovo-ideapad-110-15isk:/var/www/c_code/作業系統$ ./2
before fork pid:7203
parent:pid:7203
abc:11
child:7204, parent:7203
abc:11fork after ...
shanlei@shanlei-lenovo-ideapad-110-15isk:/var/www/c_code/作業系統$
檢視執行時的程序表:
f s uid pid ppid c pri ni addr sz wchan tty time cmd
0 s 1000 7203 5576 0 80 0 - 1127 hrtime pts/0 00:00:00 2
1 z 1000 7204 7203 0 80 0 - 0 - pts/0 00:00:00 0
4 r 1000 7205 7084 0 80 0 - 9006 - pts/1 00:00:00 ps
注意:在程序表中程序狀態位於列s,狀態位為z的是殭屍程序,子程序的程序識別符號(pid)位於列pid,而父程序的識別符號則位於列ppid。
殭屍程序的危害:
如果不呼叫wait / waitpid的話,保留的那段資訊可能會一直存在,那麼將會一直占用著程序號,如果系統中存在大量的殭屍程序,將會造成程序號短缺而無法產生新程序。並且很可能造成資源洩露。
如何避免殭屍程序
1.通過訊號機制,子程序退出時向父程序傳送sigchild訊號,父程序處理sigchild訊號。在訊號處理函式中呼叫wait/waitpid進行處理殭屍程序。**如下:
#include
#include
#include
#include
#include
#include
#include
#include
static
void
sig_child
(int signo)
;//殭屍程序
intmain
(void
)else
if(pid ==0)
else
printf
("fork after ... \n");
}static
void
sig_child
(int signo)
2.或者fork兩次,原理是將子程序成為孤兒程序,從而其的父程序變為init程序,通過init程序可以處理殭屍程序。(這種方法不是很理解,所以沒有**…哪位好心人能給我講一講嗎?)
如果父程序沒有呼叫wait()就終止了,那麼對於該父程序的子程序將會成為孤兒程序(orphan process)。linux/unix對這種情況的處理是:將init程序作為孤兒程序的父程序,程序init定期呼叫wait(),以便收集任何孤兒程序的退出狀態,並釋放孤兒程序識別符號和程序表條目。
#include
#include
#include
#include
//孤兒程序
intmain
(void
)else
if(pid ==0)
else
return0;
}
執行結果:
shanlei@shanlei-lenovo-ideapad-110-15isk:/var/www/c_code/作業系統$ ./3
i am child, pid=8300, ppid=8299
i am parent, pid=8299
shanlei@shanlei-lenovo-ideapad-110-15isk:/var/www/c_code/作業系統$ i am child, pid=8300, ppid=1
程序表條目:
f s uid pid ppid c pri ni addr sz wchan tty time cmd
4 s 0 1 0 0 80 0 - 56380 - ? 00:00:09 systemd
....
1 s 1000 8300 1 0 80 0 - 1127 hrtime pts/0 00:00:00 3
4 r 1000 8301 7084 0 80 0 - 9006 - pts/1 00:00:00 ps
由於子程序sleep了10s,所以父程序終止時,子程序還沒有結束,此時將會該子程序成為孤兒程序,可以看到這個時候該孤兒程序的父程序pid為1,也就是所謂的systemd(init)程序。
init程序就好像是乙個民政局,專門負責處理孤兒程序的善後工作。每當出現乙個孤兒程序的時候,核心就把孤 兒程序的父程序設定為init,而init程序會迴圈地wait()它的已經退出的子程序。這樣,當乙個孤兒程序淒涼地結束了其生命週期的時候,init程序就會代表黨和**出面處理它的一切善後工作。因此孤兒程序並不會有什麼危害。
殭屍程序和孤兒程序
殭屍程序 乙個子程序在其父程序還沒有呼叫wait 或waitpid 的情況下退出。這個子程序就是殭屍程序。孤兒程序 乙個父程序退出,而它的乙個或多個子程序還在執行,那麼那些子程序將成為孤兒程序。孤兒程序將被init程序 程序號為1 所收養,並由init程序對它們完成狀態收集工作。殭屍程序將會導致資源...
殭屍程序和孤兒程序
什麼是殭屍程序?乙個子程序在其父程序沒有呼叫wait 或waitpid 的情況下退出。這個子程序就是殭屍程序。如果其父程序還存在而一直不呼叫wait,則該殭屍程序將無法 等到父程序結束後,會被init 驗證 include include includeint main 3秒後查詢其程序資訊 通過上...
殭屍程序和孤兒程序
殭屍程序和孤兒程序 在unix系統程式設計中,常常會碰到兩個概念 僵死程序和孤兒程序 僵死程序 在unix程序模型中,程序是按照父程序產生子程序,子程序產生子子程序這樣的方式建立出完成各項相互協作功能的程序的。當乙個程序完成它的工作終止之後,它的父程序需要呼叫wait 或者waitpid 系統呼叫取...