僵尸进程和孤儿进程

僵尸进程
  • 给进程设置僵尸进程是为了维护子进程的信息,以便于父进程在以后的某个时间获取这些信息包括(进程ID,终止状态以及资源利用信息(CPU时间,内存使用量))
  • 僵尸状态:当进程退出父进程没有读取到子进程退出的返回代码时就会产生僵尸进程(也就是子进程退出的时候父进程没有调用wait/waitpid)。
  • 僵尸进程会以终止状态保存在进程表中,并且会一直在等待父进程读取退出状态码。
  • 所以只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态
模拟实现僵尸进程
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>                                                
#include<unistd.h>

int main()
{
     int ret = fork();
     if(ret < 0)
     {
         perror("fork");
         return 1;
     }
     else if( ret > 0 )//父进程睡眠30秒,从而不能处理子进程发来的进程信息
     {
         printf("parent[%d] is sleeping..... \n",getpid());
         sleep(30);
     }
     else//形成僵尸进程
     {
         printf("child[%d] id a z...\n",getpid());
         sleep(5);
         exit(EXIT_SUCCESS);
     }                                                               
     return 0;
}
[root@localhost process]# ./a.out
parent[12452] is sleeping.....
child[12453] id a z...

利用ptrace系统追踪进程运行
运行结果进程号为12453的进程在子进程退出后,从S状态编程Z状态


僵尸进程的危害
  • 首先进程的退出状态会一直保持下去,他要返回给父进程交给他的任务完成情况,所以父进程一直不读取,那么子进程就会处于Z状态。
  • 维护进程状态本身就要用数据维护,也属于进程基本信息,保存task_struct(PCB)结构体中,所以Z状态退出,PCB就要一直维护
  • 内存浪费
  • 如果系统产生大量的僵尸进程,这些僵尸进程占用大量的进程号,那么将没有可以用的进程号从而系统不能产生进程。

孤儿进程
  • 父进程先退出,那么子进程就称为孤儿进程
  • 孤儿进程被1号init进程领养,当然有init进程(0号进程linux引导中创建的第一个进程,完成加载系统进程后,演变为系统调度,交换及存储管理进程,1号进程由0号进程创建,1号进程负责执行内核的初始化工作及进行系统配置,并创建若干个用于高速缓存和虚拟主存管理的内核线程)回收
模拟实现孤儿进程
代码
  1 #include<stdio.h>                                            
  2 #include<stdlib.h>
  3 #include<sys/types.h>
  4 #include<unistd.h>
  5
  6 int main()
  7 {
  8     pid_t pid = fork();
  9     if(pid < 0)
10     {
11         perror("fork");
12         return 1;
13     }
14     else if(pid == 0)
15     {
16         printf("I am a child :[%d] : %d\n",getpid(),pid);
17         sleep(30);
18     }
19     else
20     {
21         printf("I am parent:[%d] : %d\n",getpid(),pid);
22         sleep(5);
23         exit(0);
24     }
25     return 0;
26 }   
运行结果
[root@localhost process]# ./a.out
I am parent:[13455] : 13456
I am a child :[13456] : 0
[root@localhost process]# while :; do ps aux | grep a.out | grep -v grep; sleep 1; echo "###########"; done
###########
###########
###########
###########
root     13455  0.0  0.0   1868   360 pts/0    S+   21:45   0:00 ./a.out
root     13456  0.0  0.0   1868   228 pts/0    S+   21:45   0:00 ./a.out
###########
root     13456  0.0  0.0   1868   228 pts/0    S    21:45   0:00 ./a.out
//当父进程结束后,子进程由S+状态变为S状态

孤儿进程的处理:
  • 当产生孤儿进程进程的时候,内核就把孤儿进程的父进程设置成init,而init进程会循环的wait()它已经退出的子进程,因此孤儿进程就不会有啥危害。
阅读更多
个人分类: linux
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭