一、殭屍進程:當前進程運行結束,但其資源沒有被回收;
二、驗證方法:
1.用fork函數創建兩個進程,讓子進程退出,父進程不調用wait/waitpid爲子進程回收資源;(代碼如下)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
pid_t pid;
if( (pid = fork()) < 0)
{
perror("fork error");
exit(1);
}
else if(pid == 0)
{
printf("im child\n");
}
else if(pid > 0)
{
printf("im farther\n");
while(1)
;
}
return 0;
}
2.編譯-執行,如下圖;
3.新建另一個終端(shift+Ctrl+n),然後輸入查看進程命令 ps -ajx, 現象如下圖(Z+:前臺運行的殭屍進程);
三、殭屍進程的危害
由於子進程的結束和父進程的運行是一個異步過程,即父進程永遠無法預測子進程 到底什麼時候結束. 那麼會不會因爲父進程太忙來不及wait子進程,或者說不知道 子進程什麼時候結束,而丟失子進程結束時的狀態信息呢?
不會。因爲UNⅨ提供了一種機制可以保證只要父進程想知道子進程結束時的狀態信息, 就可以得到。這種機制就是: 在每個進程退出的時候,內核釋放該進程所有的資源,包括打開的文件,佔用的內存等。但是仍然爲其保留一定的信息(包括進程號the process ID,退出狀態the termination status of the process,運行時間the amount of CPU time taken by the process等)。直到父進程通過wait / waitpid來取時才釋放. 但這樣就導致了問題,如果進程不調用wait / waitpid的話,那麼保留的那段信息就不會釋放,其進程號就會一直被佔用,但是系統所能使用的進程號是有限的,如果大量的產生僵死進程,將因爲沒有可用的進程號而導致系統不能產生新的進程. 此即爲殭屍進程的危害,應當避免。
四、避免方法(具體方法見下一博客)
1.讓父進程先於子進程退出,即讓子進程成爲孤兒進程,此時,子進程會被1號進程(init進程)所收養,當子進程結束時,1號進程會爲子進程回收系統資源(APUE中講了調用兩次fork,形成一個孫子進程,讓孫子進程變成孤兒進程來避免殭屍進程);
2.父進程調用wait函數及waitpid函數,以阻塞或非阻塞輪訓的方式來等待子進程的退出,併爲子進程回收系統資源;