系统相关
首页 > 系统相关> > 孤儿进程与僵尸进程

孤儿进程与僵尸进程

作者:互联网

前言

首先,我们应知道在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