linux下的僵死进程

1.僵死进程是什么?
linux下每个进程都有进程号,在进程结束的时候,调用了exit,进程其实并未完全死亡,它会遗留一些少量的信息,例如进程号,进程开始时间等,我们称之为进程的尸体,最后这些尸体由系统回收,释放出被占用的进程号。这是进程结束的大概流程。
我们知道有父子进程的概念,例如通过fork函数,可以创造出一个子进程来,每个子进程在结束时会给父进程发出一个信号,这个信号为sigchild信号,当父进程中有sigchild处理函数调用wait或者waitpid时,会给已经结束的子进程收尸,从而释放子进程占用的那部分进程号,这是正常的情况下。但僵死进程就与之相反,如果父进程由于代码设置或者功能所需卡在一个循环里,例如while(1)无限循环中,或者因为其他原因导致迟迟无法处理sigchild信号。这个父进程的子进程又早早的结束,这就会导致父进程无法处理子进程发回的信号,就没办法给子进程收尸。这个时刻子进程其实已经名存实亡了,因为它结束了所以它几乎不占用内存空间,但它又没有彻底的死去,因为它还占用着进程号。这个状态的子进程就是僵死进程。有人又叫它僵尸进程,因为就像僵尸那样,死了没人给收尸还在一直存在着。

2.那么如何模拟僵死进程呢。
其实只要一段简单的代码,例如
#include

int main(void)
{
int res=fork();
   if(res==0)
  {
  printf("son course is over");
  }
else
{
while(1);
}
return 0;
}
这段代码子进程会输出 son course is over(子进程结束),然而父进程会卡在else里的while(1)中无限循环,只要我不终止程序,子进程会永远僵死下去。



3.那么僵死进程会带来什么影响?
之前说过僵死进程其实已经结束了,所以不会占用内存空间,所谓的尸体即保留的开始时间之类的信息而占用的空间 也对系统来说无伤大雅,九牛一毛,杯水车薪.......,这么听起来似乎没什么很大的消极作用,其实不然,之前也说过僵死进程会占用进程号,当僵死进程过多时,大量的进程号会被占用,新进程从而无法获得进程号,那么系统也自然会出问题。所以说及时高效的清理僵死进程还是尤为重要的。

4.如何清除僵死进程?
  (1)上面关于僵死进程的产生可以推想到,僵死进程是由于其父进程未能及时给自己收尸导致的,那么我们干脆就杀死父进程,这时的僵死进程就变为了孤儿进程,孤儿进程的处理方法我们也知道是会被系统init孤儿院 收养,然后杀死(确定是孤儿院不是变态屠宰场?),这个方法就有点暴力了,如果因为需求,不想杀死父进程又想清理其变为僵死进程的子进程该如何做呢?

    (2)例如我父进程最后就有个sleep(1000)的代码,它是程序功能所需,不能提前杀死,那该如何给子进程收尸呢,如果不收尸,这个子进程将占用进程号至少1000秒,这显然是不好的。就要想起最开始说过的关于收尸的原理。
是父进程接受sigchild信号后调用wait/waitpid进行收尸,但父进程陷入了睡眠或者循环无法脱身去调用该怎么办呢,不难想到,如果父子进程无要求完成的先后顺序,可以估算子进程运行时间,然后让父进程睡眠子进程的运行时间,然后刚刚睡眠后 在父进程进入长循环或下一次功能所需的睡眠前,设置一个接受sigchild信号后的处理函数,手动收尸,既腾出了子进程的进程号,又不影响父进程的功能 ,但是这样有一个问题,如果子进程运行的时间很长。那父进程岂不是要睡很久?这和阻塞就一样了。
(3)所以基于父子进程同时运行互不影响的需求,又要父进程能时时刻刻关注子进程死活,如果死了立刻做出收尸的动作。目前很难想到一种方法去解决它。因此就有了信号概念的产生。至于比较完美的处理僵死进程的方法,在我的下篇博客里有举例说明。感兴趣的可以看看。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值