僵尸进程,孤儿进程及代码实现

僵尸进程

父进程调用fork()创建子进程,通常情况下,子进程运行时,父进程调用wait()或waitpid()函数等待子进程,子进程退出后,父进程接收到子进程的退出码,并释放子进程资源。
但如果父进程没有接收到子进程的退出码,那子进程的资源便无法回收,子进程将会以终止状态保持在进程表中,直到父进程读取它的退出码,这种子进程也就叫僵尸进程。

僵尸进程的危害

1.僵尸进程虽然已经不再工作,但它自己那部分资源却未得到释放,会造成内存泄漏
2.计算机能够运行的进程是有限的,僵尸进程过多将导致新进程无法创建
3.僵尸进程一直保持退出状态,这是需要task_struct维护的,有一定开销。

模拟实现僵尸进程

//模拟一个持续30s的僵尸进程

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<stdlib.h>
  4 
  5 
  6 int main()
  7 {
  8     pid_t pid = fork();//创建一个子进程
  9 
 10     if (pid<0)//创建子进程失败
 11     {
 12         printf("create child process is failed!!\n");
 13     }
 14 
 15     else if (pid >0)//父进程
 16     {
 17         printf("parent process is sleeping:%d\n",getpid());
 18         sleep(30);
 19     }
 20     else//子进程
 21     {
 22         printf("this is child process");
 23         sleep(5);
 24         exit(EXIT_SUCCESS);
 25     }
 26     return 0;
 27 
 28 }

运行上面的代码,我们用ps -aux查看一下进程的状态:
这里写图片描述
我们发现,这个pid为3415的进程就是我们所要的僵尸进程zombie。
再用kill -9试着强制终止该进程:
这里写图片描述
连kill -9这样的强制命令都无法终止僵尸进程,可见僵尸进程在计算机内是多么顽固的存在。
正确处理僵尸进程的方法是调用wait()或者waitpid()函数,让父进程及时接收到子进程返回的SIGCHID信号并释放资源。


孤儿进程

当父进程先于子进程退出,子进程就成为孤儿进程,子进程会被孤儿院init进程领养(意为init进程作为子进程的新父进程),由init进程为他回收资源。

代码实现

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 
  4 
  5 int main()
  6 {
  7     pid_t pid = fork(); //创建子进程
  8     if (pid < 0)//创建失败
  9     {
 10         printf("fork error!!\n");
 11         return -1;
 12     }
 13     else if (pid >0)//父进程
 14     {
 15         printf("father is gone!!\n");
 16         exit(EXIT_SUCCESS);
 17     }
 18     else//子进程
 19     {
 20         printf("my father is gone!!  %d\n",getpid());
 21         sleep(20);
 22     }
 23     return 0;
 24 }

上述代码运行后,结果如下:
这里写图片描述
我们再来看一下子进程的状态:
这里写图片描述
由图可知,子进程已经被1号进程(init进程)领养,1号进程来为该进程释放资源。

猜你喜欢

转载自blog.csdn.net/Ferlan/article/details/82595505