Linux:孤儿进程与僵尸进程(源码及操作过程)

编译环境:Ubuntu 18.04

孤儿进程:
顾名思义,父亲有个孩子,然而父亲英年早逝,孩子便成了孤儿,也就是孤儿进程
在早期的Ubuntu版本中,孤儿进程会被init进程”领养“,init进程便成为了该孤儿进程的父进程。Ubuntu 16.04版本开始,孤儿进程会被当前操作系统的UI进程”领养“。
这种“领养”行为就是为了释放子进程所占用的系统资源。进程结束后,会释放用户区空间,但是释放不了PCB,PCB必须由它的父进程释放,因此必须“领养”。
guer.c

 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 
 int main(int argc,char *argv[])
 {
     pid_t pid;
     pid = fork();
 
     if(pid == 0)
     {
         sleep(1);//让子进程睡一会儿
         printf("child pid = %d,ppid = %d\n",getpid(),getppid());//打印进程ID
     }else if(pid > 0)
          {
              printf("parent pid = %d,ppid = %d\n",getpid(),getppid());//打印进程ID
          }
     
     return 0;
 }                           

Linux:孤儿进程与僵尸进程(源码及操作过程)_第1张图片
此时,右侧打印输出parent pid = 26054,ppid = 17558之后父进程就结束死去了,而child pid = 26055,ppid = 2565之中,ppid其实是他养父的id。利用ps aux | grep 2565命令查到其养父为systemd,也就是当前操作系统的UI进程,如果此时用kill -9 2565命令杀死该养父进程,则会造成系统注销。

僵尸进程:
顾名思义,孩子死了,爹还活着,爹不去释放子进程的PCB,孩子就成了僵尸进程
不能被称为活着的进程,是一个已经死掉的进程
jiangshi.c

#include 
 #include 
 #include 
 #include 
 #include 
 #include 
 
 int main(int argc,char *argv[])
 {
     pid_t pid;
     pid = fork();
 
     if(pid == 0)
     {
         sleep(1);//让子进程睡一会儿
         printf("child pid = %d,ppid = %d\n",getpid(),getppid());//打印进程ID
     }else if(pid > 0)
          {
              printf("parent pid = %d,ppid = %d\n",getpid(),getppid());//打印进程ID
          }
     
     return 0;
 }

Linux:孤儿进程与僵尸进程(源码及操作过程)_第2张图片
从右侧打印输出可以看出,父进程没有被杀死,一直执行打印id的命令。
使用ps aux命令查看当前所有进程
Linux:孤儿进程与僵尸进程(源码及操作过程)_第3张图片
可以发现名为 [./a.out] 的进程就是僵尸进程,它的pid号为26798,其父进程名为 ./a.out,pid号为26797。此时使用kill -9 26797杀死僵尸进程的父进程,便可杀死僵尸进程。如下图:
Linux:孤儿进程与僵尸进程(源码及操作过程)_第4张图片
此时,再次使用ps aux命令查看当前所有进程会发现僵尸进程及其父进程已消失。

你可能感兴趣的:(Linux)