1. 程式人生 > >關於孤兒進程和僵屍進程的實踐

關於孤兒進程和僵屍進程的實踐

進程管理

首先關於孤兒進程

processA processB processC

ps -ef|grep process

sroot 9665 24982 0 23:42 pts/0 00:00:00 /bin/bash ./processA.sh

sroot 9666 9665 023:42 pts/0 00:00:00 /bin/bash./processB.sh

sroot 9667 9666 023:42 pts/0 00:00:00 /bin/bash./processC.sh

24982 -> 9665 /processA.sh ->9666 ./processB.sh ->9667 ./processC.sh

24982是INIT下/bin/bash .

[[email protected] 24982]# pwd

/proc/24982

[[email protected] 24982]# ll

total 0


lrwxrwxrwx. 1 sroot root 0 Jun 22 23:45 cwd -> /home/craft/shell

-r--------. 1 sroot root 0 Jun 22 23:45 environ

lrwxrwxrwx. 1 sroot root 0 Jun 22 23:32 exe -> /bin/bash


[[email protected]

/* */ 24982]# ps -ef |grep 24982

sroot 9665 24982 0 23:42 pts/0 00:00:00 /bin/bash ./processA.sh

sroot 19995 2740 023:47 pts/1 00:00:00 grep 24982

sroot 24982 24935 0 23:32 pts/0 00:00:00 bash

之後,kill -9 processB AC的變化

[[email protected] 24982]# ps aux |grep process

sroot 17693 0.0 0.0 106104 1172 pts/0 S+ 00:22 0:00 /bin/bash./processA.sh

sroot 17694 0.0 0.0 106104 1172 pts/0 S+ 00:22 0:00 /bin/bash./processB.sh

sroot 17695 32.8 0.0 106108 1192 pts/0 S+ 00:22 0:01 /bin/bash ./processC.sh

ps aux |grep process

只剩下一個/processC.shAB 都不見了

sroot 17695 36.2 0.0 106108 1192 pts/0 R 00:22 0:12 /bin/bash ./processC.sh

也就是B死掉的時候,會去通知他的父進程A

本身A的存在就是等待B 完成的,所以B死掉,A也釋放了。

但是C並不知道。

這個時候A不停的繼續跑,並且無法用ctrl+c結束。

知道kill -9 processC的進程號。

這個時候並不會產生僵屍進程

此時,C就是孤兒進程。

如何產生僵屍進程

首先,僵屍進程是由於父進程沒有回收子進程。

父進程會使用wait函數來等待子進程若子進程結束,用這個函數來回收子進程。

#include <stdio.h>

#include <sys/types.h>

#include <time.h>

int main()

{

//fork a child process

pid_t pid = fork(); 產生一個子進程。新產生的子進程同樣用這個代碼。這樣就會有兩個程序在使用同一個代碼運行。

if (pid > 0) //parentprocess父進程進入這個if判斷

{

printf("in parentprocess, sleep for one miniute...zZ...\n");

struct timeval tv;

gettimeofday(&tv,NULL);

printf("parent microsecond:%ld\n",tv.tv_sec*1000000 +tv.tv_usec); //微秒 輸出當前的時間

sleep(60);

printf("aftersleeping, and exit!\n");

gettimeofday(&tv,NULL);

printf("parentmicrosecond after sleeping:%ld\n",tv.tv_sec*1000000 + tv.tv_usec); //微秒

重新輸出sleep之後的時間

}

else if (pid == 0) 子進程進入這個if判斷語句

{

//child process exit,and to be a zombie process

printf("in child process, and exit!\n");

structtimeval tv;

gettimeofday(&tv,NULL);

printf("child microsecond:%ld\n",tv.tv_sec*1000000 +tv.tv_usec); //微秒

輸出進入到子進程的時間

}

}

gcc指令編譯

[[email protected] test]# gcc zombie1.c -o zombie1

[[email protected] test]# ./zombie1 運行

運行結果如下

./zombie1

in parent process, sleep for one miniute...zZ...父進程先進入第一個判斷語句,輸出時間

parent microsecond:1498469853526179

in child process, and exit! 子進程進入判斷語句,輸出時間

child microsecond:1498469853526404

after sleeping, and exit!

parent microsecond aftersleeping:1498469913532272 父進程結束sleep,輸出時間,這個時間跟第一個輸出時間相差為60s

技術分享

ps查看進程情況

[[email protected] test]# ps aux |grep zombie

root 3445 0.0 0.0 3924 416 pts/2 S+ 05:37 0:00 ./zombie1

root 3446 0.0 0.0 0 0 pts/2 Z+ 05:37 0:00 [zombie1]<defunct>

出現一個僵屍進程

[[email protected] test]# ps -ef |grep zomb

root 3445 3024 0 05:37 pts/2 00:00:00./zombie1

root 3446 3445 0 05:37 pts/2 00:00:00 [zombie1] <defunct>

從進程ID能看出這個僵屍進程是zombie的子進程

  • killdefunct進程方法有二:

  • 1,重啟服務器電腦,這個是最簡單,最易用的方法,但是如果你服務器電腦上運行有其他的程序,那麽這個方法,代價很大。
    所以,盡量使用下面一種方法

  • 2,找到該defunct僵屍進程的父進程,將該進程的父進程殺掉,則此defunct進程將自動消失。


關於孤兒進程和僵屍進程的實踐