殭屍進程是指的父進程已經“異常退出”,而子進程dead之後沒有進程接受,就成為殭屍進程.(zombie)進程,
注意,是針對子進程來講的,而不是父進程。
怎樣產生殭屍進程的:
一個進程在調用exit命令結束自己的生命的時候,其實它並沒有真正的被銷毀,而是留下一個稱為殭屍進程(Zombie)的資料結構(系統調用 exit,它的作用是使進程退出,但也僅僅限於將一個正常的進程變成一個殭屍進程,並不能將其完全銷毀)。在Linux進程的狀態中,殭屍進程是非常特殊的一種,它已經放棄了幾乎所有記憶體空間,沒有任何可執行代碼,也不能被調度,僅僅在進程列表中保留一個位置,記載該進程的退出狀態等資訊供其他進程收集,除此之外,殭屍進程不再佔有任何記憶體空間。它需要它的父進程來為它收屍,如果他的父進程沒安裝
SIGCHLD訊號處理函數調用wait或waitpid()等待子進程結束,又沒有顯式忽略該訊號,那麼它就一直保持殭屍狀態,如果這時父進程結束了,那麼init進程自動會接手這個子進程,為它收屍,它還是能被清除的。但是如果如果父進程是一個迴圈,不會結束,那麼子進程就會一直保持殭屍狀態,這就是 為什麼系統中有時會有很多的殭屍進程。
由此看出,殭屍進程並不會佔用很多的資源。唯一的危害是影響了系統最大進程數。
如何查看殭屍進程?
ps auwx;發現殭屍進程的狀態為Z。
ps axf;看進程數,以樹的方式。
ps auwx | cut -c 10-15,45-50,63- | grep -i Z 查看殭屍進程pid、名稱和進程路徑。
應用實例:
#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <sys/wait.h>const char cmd_init[]="ps -o pid,ppid,state,tty,command";int main(int argc,char **argv){ pid_t pid; if((pid=fork()) < 0){ exit(-1); } else if(pid==0){ /* 子進程exit */ exit(0); } sleep(5); system(cmd_init); exit(0);}
後臺運行此程式。
./a.out &
總結
1.父進程先於子進程退出,子進程的狀態是 "zombie" 殭屍狀態。
如果父進程正常終止,子進程執行完畢之後會跟著消亡;
如果父進程是異常終止,則子進程被託管給init進程,而子進程的狀態則會一直是殭屍進程狀態!
2.子進程先於父進程退出,這是很正常的情況了。子進程退出之後,父進程尚未退出,等待父進程退出的時候,定會收拾子進程的資訊。
因此不會有什麽殭屍進程只說。但是,如果父進程異常退出,那麼子進程依然會是殭屍進程。