linux处理僵死进程 及 信号

信号的概念:
 系统预先定义好的某些特定事件:可以被发生,也可以被接受。发生和接受的主体都是进程。
信号的响应方式有以下几种:
      默认0
     
 忽略1    
     
  自定义
     
SIG_DFL    
 SIG_IGN  
     
   0  
     
      1
    
可以同过signal函数修改信号的响应方式
    typedef void
(*fun_handle)(int );
    fun_handle signal(int
sig_num,fun_handle fun);
  fun参数简单来理解就是自己定义的相应方式的函数。
signal一般在进程刚开始的时候 即main()里 第一行调用
接下来将用处理僵死进程来说明signal函数的作用
制造僵死进程的代码如下
#include<stdio.h>
#iclude<signal.h>
int main(void)
 int res=fork();
if(res==0)
{
sleep(2);
printf("kid start");
sleep(2);
printf("kid  over")
}
  else
{
printf("father start");
while(1);
}
return 0;
}
上面代码的运行结果应该是先是father start 打印在屏幕上,过了2秒 kid start 打在了屏幕上。又过了2秒
 kid
over打印在了屏幕上,至此,子进程已经运行结束了,父进程仍在while(1)中,子进程就变成了僵死进程。
如何让处理僵死的子进程呢。
子进程结束的时候都会向父进程发送一个信号。(这是系统默认会做的)
父进程会在运行即将结束的时候处理这个信号。杀掉子进程,让它占用的pcb释放。(这也是默认的)
但僵死进程出现的原因就是因为往往父进程要运行的时间往往很长,不能及时处理这个信号,导致子进程必须随着父进程的慢节奏才能被收尸。这是我们不希望看到的。
因此我们要修改父进程中,处理子进程信号的函数。让它达到一种效果。那就是父子进程可以同时开始运行,如果子进程一结束发回信号,父进程就能立刻调用处理函数来杀掉子进程
(杀子进程的时间微乎其微可以忽略),然后再继续运行父进程。让父进程也不会阻塞 (其实是有的,但时间很短可以忽略)。
由于子进程发回的是SIGCHLD信号,因此我们就要用signal函数对SIGCHILD信号进行处理。
signal(SIGCHLD,0)为默认当然不是我们想要的,默认的话就会出现僵尸进程。
signal(SIGCHLD,1)为忽略
当然也不是我们想要的,这样的话就算父进程结束,子进程也没人给收尸了,因为就算父进程结束,接受了SIGCHLD信号也视而不见。既然看不见SIGCHLD信号那就不会做出给子进程收尸的反映了。我们知道很基本的原理就是
   给信号---做反应。
所以我们要自定义一种处理的方式。
signal(SIGCHLD,fx);
fx就是一个函数 。执行fx里面的内容就是对SIGCHLD做的反映。
因此我们就写一个处理子进程的函数
void fx(int a)
{
   wait(NULL);
   printf("son is killed by
fx()!");
}
一旦子进程结束发回了SIGCHLD信号,父进程立刻对SIGCHLD信号做出反应。原本的反应应该是等父进程运行快结束再wait子进程。但我们用了signal修改了反应的内容,那就是立刻调用fx函数。fx会立刻wait子进程。然后潇洒的打印一句
son is killed by fx()!;
 这样的话,子进程就立刻被释放了,我们也达到了即使处理僵死进程的目的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值