系统相关
首页 > 系统相关> > 僵尸进程和孤儿进程的理解

僵尸进程和孤儿进程的理解

作者:互联网

文章目录

1.僵尸进程

1.1僵尸进程的基本概念

一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中,这种进程称为僵尸进程。一般来说:只要子进程退出,父进程还没有退出,父进程没有获取到子进程的状态信息,子进程就会进入到僵尸状态。

1.2 僵尸进程的危害

我们知道:在每个进程退出的时候,操作系统会释放该进程所有的资源,包括打开的文件,占用的内存等。 但是仍然为其保留一定的信息(包括进程号 退出状态,运行时间等)。为了能够让父进程得知子进程什么时候退出,父进程需要调用wait/waitpid来获取子进程终止时的状态信息。
如果进程不调用wait / waitpid的话, 那么保留的那段信息就不会释放,由于是进程的信息,所以它被保存在PCB中,PCB是一个结构体,那么它本身就要占据内存空间,因此会造成内存的泄漏,应当尽量避免。

1.3 僵尸进程的模拟

如下所示:我们让子进程先于父进程退出,让父进程进入死循环,子进程sleep10秒之后,进行退出。此时子进程就进入了僵尸状态。

  1 #include <stdio.h>
  2 #include <unistd.h>
  3 int main()
  4 {
  5     pid_t ret =fork();
  6     if(ret == -1)
  7         printf("子进程创建失败");
  8     else if(ret ==0)
  9     {
 10         printf("i am child ,my pid is %d,my father pid is %d\n",getpid(),getppid());
 11         sleep(10);
 12         _exit(99);                                                                                                
 13     }
 14     while(1)
 15     {
 16         printf("i am father ,my pid is%d\n",getpid());
 17         sleep(1);
 18     }
 19     return 0;
 20 }

在这里插入图片描述在这里插入图片描述

1.4 僵尸进程的解决方案

  1. 直接杀死父进程,kill -9 [父进程的pid],强力杀死,极度不推荐!
  2. 优雅的使用wait/waitpid函数来获取子进程的状态信息,将其销毁,从而避免僵尸进程的产生。本质上是子进程结束之后,会给父进程发生一个SIGCHID信号,当父进程接收到该信号之后,再调用wait函数从而清除子进程的信息和资源。

2.孤儿进程

2.1孤儿进程的基本概念

孤儿进程是父进程先于子进程结束,当子进程没有自己的爸爸时,子进程就会被init进程收养,从而变成了孤儿进程。

  1 #include <stdio.h>                                                                                                
  2 #include <unistd.h>
  3 #include <stdlib.h>
  4 int main()
  5 {
  6    pid_t pid =fork();
  7    if(pid == -1)
  8    {
  9        perror("fork失败");
 10        exit(-1);
 11    }
 12    else if (pid == 0)
 13    {
 14        while(1)
 15        {
 16            printf("i am child ,my pid is %d,my father is %d\n",getpid(),getppid());
 17            sleep(2);
 18        }
 19    }
 20    else if(pid >0)
 21    {
 22        printf("i am father ,my pid is %d\n",getpid());
 23        sleep(10);
 24        exit(99);
 25    }
 26     return 0;
 27 } 

在这里插入图片描述
在这里插入图片描述

可以看出来,当父进程没有结束时,子进程的父进程没有改变,而当父进程退出之后,子进程被1号进程领养,注意没有孤儿状态这一说法。
init进程就好像是一个民政局,专门负责处理孤儿进程的善后工作。每当出现一个孤儿进程的时候,内核就把孤儿进程的父进程设置为init。这样,当一个孤儿进程凄凉地结束了其生命周期的时候,init进程就会代表党和政府出面处理它的一切善后工作。因此孤儿进程并不会有什么危害。

标签:僵尸,pid,孤儿,进程,include,my
来源: https://blog.csdn.net/tjh1998/article/details/115354261