孤儿进程与僵尸进程
作者:互联网
前言
首先,我们应知道在unix/linux中,正常情况下,子进程是通过父进程创建的,子进程再去创建新的子进程(也不一定)。一旦子进程被创建完毕,子进程与父进程是两个独立的进程,二者的运行与结束是一个异步过程,也就是说父进程无法预知子进程什么时候结束,子进程也不知道父进程什么时候需要自己的状态。那么当子进程完成自己的工作后,父进程需要调用接口wait()/waitpid(),获取子进程的状态。
孤儿进程
概念
孤儿进程是指父进程先于子进程结束,那么此父进程创建的子进程将成为孤儿进程,进而被init进程(pid为1)领养,由1号进程完成状态收集工作。
测试
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
int ret = fork();
if(ret == 0){
printf("i am child,my pid is %d,myfather is %d\n",getpid(),getppid());
sleep(8);
printf("my father went to heaven!i became a orphan,but %d adopted me.\n",getppid());
}
else if(ret > 0 ){
printf("i am father,my pid is %d,my father is %d\n",getpid(),getppid());
sleep(5);
printf("我溜了溜了!孩子你自己耍叭\n");
}
else{
perror("fork");
return 1;
}
return 0;
}
测试结果:
危害
孤儿进程是没有父进程的过程,而init进程就像一位慈善家一样,见到孤儿进程就收养。孤儿进程产生后,init进程对其认领收养,之后获取其状态信息进行处理,因此孤儿进程并不会占用系统资源,所以孤儿进程没有危害
【注意】:只有孤儿进程,没有孤儿状态!!!
僵尸进程
概念
某进程使用fork()创建子进程,子进程工作结束,但父进程并没有调用wait()/waitpid()获取子进程的状态信息,对子进程的状态不予理会。那么子进程的进程描述符仍将保存在操作系统中,占用资源。这种进程称为僵尸(僵死)进程。
Z+:僵死状态
测试
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
int ret = fork();
if(ret == 0){
printf("i am child,my pid is %d,myfather is %d\n",getpid(),getppid());
exit(EXIT_SUCCESS);
}
else if(ret > 0 ){
printf("i am father,my pid is %d,my father is %d\n",getpid(),getppid());
sleep(30);
}
else{
perror("fork");
return 1;
}
return 0;
}
测试结果
危害
任何一个子进程(init除外)在exit()后,并不是马上就消失,会留下一个称为僵尸进程(zombie)的的数据结构,等父进程处理。如果父进程及时处理,ps aux命令就来不及看到Z+的这样僵死状态;如果父进程不处理/处理的慢,我们使用ps aux就可以查看到Z+状态。
僵尸进程并不工作,其PCB(进程控制块)一直得不到回收,会一直占用系统资源,造成内存泄漏。
严格来说,造成危害的其实并不是僵尸进程,而是制造僵尸进程的父进程,它不处理完成工作的子进程,导致子进程成为僵尸进程。
处理方法
1.重启操作系统【这么干估计要被枪毙】
2.枪毙父进程(kill [pid]/kill -9 [pid])【不推荐,因为一个父进程可能有许多子进程,枪毙父进程,意味着要牵连无辜的子进程】
3.进程等待
标签:僵尸,pid,孤儿,printf,进程,include,my 来源: https://blog.csdn.net/qq_39208237/article/details/114962860