僵尸进程和孤儿进程的理解
作者:互联网
文章目录
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 僵尸进程的解决方案
- 直接杀死父进程,kill -9 [父进程的pid],强力杀死,极度不推荐!
- 优雅的使用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