模擬程序
#include <stdio.h> #include <unistd.h> //本程序啟動一個子進程,父子進程無限循環不退出 //編譯:gcc create_zombie.c -o zombie //執行:./zombie //使用方法 //kill父進程,則子進程變為孤兒進程,可以kill子進程解決 //kill子進程,則子進程變為僵尸進程,可以kill父進程解決 int main() { //fork一個進程,作為子進程 printf("fork a child process\n"); pid_t pid = fork(); if (pid > 0) { //父進程 printf("---i am parent: %d\n", getpid()); } else if (pid == 0) { //子進程 printf("---i am child: %d\n", getpid()); } //死循環,避免進程退出,方便人為操作模擬孤兒進程與僵尸進程 while(1) { sleep(1); } return 0; }
僵尸進程
處于僵死狀態的進程危害:會造成資源泄漏
僵尸進程的產生原因:子進程先于父進程退出,因為要保留退出原因,因此操作系統不能直接釋放所有資源,通知父進程獲取退出原因,允許操作系統釋放資源,但是父進程沒有關注這個通知導致子進程退出后無法釋放所有資源,處于僵死狀態成為僵尸進程
如何處理:結束掉父進程,僵尸進程也就結束了
如何識別:進程狀態為 Z+,可以通過 top 命令(確認僵尸進程數量)以及 ps 命令(確認進程狀態)
[root@localhost ~]# top top - 14:20:31 up 20:31, 2 users, load average: 0.31, 0.40, 0.46 Tasks: 111 total, 1 running, 109 sleeping, 0 stopped, 1 zombie [root@localhost ~]# ps -A -ostat,ppid,pid,cmd | grep -e '^[Zz]' Z+ 6720 6721 [zombie] <defunct>
孤兒進程
處于孤兒狀態的進程危害:除程序自身業務完整性外,一般來說,孤兒進程并不會有什么危害
孤兒進程的產生原因:父進程先于子進程退出,子進程就會成為孤兒進程,運行在后臺,父進程成為1號進程(init初始化進程)
如何處理:結束掉子進程即可
如何識別:進程狀態轉為后臺,即狀態沒有+號,父進程ID變為 1,可以通過 ps 命令(確認進程狀態)
[root@localhost ~]# ps -A -ostat,ppid,pid,cmd | grep zombie S+ 6858 6928 ./zombie S+ 6928 6929 ./zombie [root@localhost ~]# kill -9 6928 [root@localhost ~]# ps -A -ostat,ppid,pid,cmd | grep zombie S 1 6929 ./zombie
附錄:Linux進程狀態
D 不可中斷睡眠 (通常是在IO操作) 收到信號不喚醒和不可運行, 進程必須等待直到有中斷發生 R 正在運行或可運行(在運行隊列排隊中) S 可中斷睡眠 (休眠中, 受阻, 在等待某個條件的形成或接受到信號) T 已停止的 進程收到SIGSTOP, SIGSTP, SIGTIN, SIGTOU信號后停止運行 W 正在換頁(2.6.內核之前有效) X 死進程 (未開啟) Z 僵尸進程 進程已終止, 但進程描述符存在, 直到父進程調用wait4()系統調用后釋放BSD風格的 < 高優先級(not nice to other users) N 低優先級(nice to other users) L 頁面鎖定在內存(實時和定制的IO) s 一個信息頭 l 多線程(使用 CLONE_THREAD,像NPTL的pthreads的那樣) + 在前臺進程組
浙公網安備 33010602011771號