解决避免僵死进程的问题


  怎样产生僵尸进程的:

  一个进程在调用exit命令结束自己的生命的时候,其实它并没有真正的被销毁,而是留下一个称为僵尸进程(Zombie)的数据结构(系统调用exit,它的作用是使进程退出,但也仅仅限于将一个正常的进程变成一个僵尸进程,并不能将其完全销毁)。在Linux进程的状态中,僵尸进程

  是非常特殊的一种,它已经放弃了几乎所有内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退

  出状态等信息供其他进程收集,除此之外,僵尸进程不再占有任何内存空间。它需要它的父进程来为它收尸,如果他的父进程没安装SIGCHLD

  号处理函数调用waitwaitpid()等待子进程结束,又没有显式忽略该信号,那么它就一直保持僵尸状态,如果这时父进程结束了,那么init进程自动会接手这个子进程,为它收尸,它还是能被清除的。但是如果如果父进程是一个循环,不会结束,那么子进程就会一直保持僵尸状态,这就是为什么系统中有时会有很多的僵尸进程。

  Linux系统对运行的进程数量有限制,如果产生过多的僵尸进程占用了可用的进程号,将会导致新的进程无法生成。这就是僵尸进程对系统的最大危害。

    知道了 僵尸进程产生的原因后,就很容易清除僵尸进程了。
    避免 僵尸进程的出现的一种办法是父进程调用wait、waitpid等待子进程结束(即对其进行回收),但这样做有一个弊端就是在子进程结束前父进程会一直阻塞,不能做任何事情。另外一种更好的方法就是调用两次fork函数。
 
源代码如下:
产生 僵尸进程例子:
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
int main(int argc, char* argv[])
{
 while(1)
 {
  pid_t chi = fork();
  if(chi == 0)
  {
   execl("/bin/bash","bash","-c","ls",NULL);
  }
     sleep(2);
 }
}
 
调用两次fork函数。避免 僵尸进程例子:
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
int main(){
        pid_t pid;
  
        if((pid = fork()) < 0)
 {   //创建子进程
                perror("fork");
        }
 else if(pid == 0)//子进程1
 {      
  if((pid = fork()) < 0)//由子进程1创建子进程2
  {    
   perror("fork");
  }
  else if(pid > 0)
  {
   printf(" child,parent pid = %d\n",getppid());
   exit(0);       //子进程1结束
  }
  else//子进程2
  {        
   printf("second child,parent pid = %d\n",getppid());  //打印子进程2的父进程
    sleep(30);
   exit(0);
  }
  
 }
 else //父进程
 {      
                /* do something else*/
  waitpid(0,NULL,0);//收集子进程1结束
  sleep(60);  
 }
 return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值