首页 > 代码库 > 关于孤儿进程和僵尸进程的实践

关于孤儿进程和僵尸进程的实践

首先关于孤儿进程 

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 .

[sroot@AAEP7151 24982]# pwd

/proc/24982  

[sroot@AAEP7151 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


 

[sroot@AAEP7151 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的变化

 

[sroot@AAEP7151 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指令编译

[root@localhost test]# gcc zombie1.c -o zombie1

 

[root@localhost 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查看进程情况

[root@localhost 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>

 

出现一个僵尸进程

[root@localhost 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进程将自动消失。


关于孤儿进程和僵尸进程的实践