unix中的signal处理过程

Unix中的signal用于通知进程中发生了异步事件。用户可以通过kill系统调用发送一个信号,kernel自己内部也可以发送信号给一个进程。

进程对信号可以有三种处理方式:忽略,处理和默认(exit)。

为了发送一个信号给一个进程,内核设置相对应于信号的bit位在进程的process table entry中,例如如果进程收到一个kill signal,它将设置相应的bit位在process table signal field,但是进程不能得知它接收了多少次这个信号。如果一个进程睡眠在一个可以被中断的级别上,内核将会唤醒这个睡眠的进程,进程的发送者至此完成任务。

内核仅当一个进程从kernel mode返回user mode时才处理一个信号。如果一个进程在user mode运行,且内核正在处理“一个发送信号给这个进程”的中断,内核将会在它返回user mode之前识别并且处理这个信号。

 

进程可以通过signal(signmu,handler);系统调用设置对信号的处理方式。在进程的u area中包含了一个signal-hanlder field,对应每个signal num和相应的处理函数。

当处理一个信号时,内核确定信号的类型,并在process table entry中设置该信号的bit位。如果该信号的处理方式被设置为default,内核将会在exit之前为此进程产生一个" core"。但是内核不会为产生core如果没有一个程序错误发生,例如信号SIG_INT和hang信号。但是quit信号仍然产生一个core,即使它在进程运行环境外产生,这通常是用户结束一个无限循环等。

当进程接收到一个信号后,在返回user mode之前,内核会做一些事:

1,保存的register context为返回user process。

2,清除在进程的u area中的signal handler field,设置它为default状态(如果设置了“忽略”状态,内核并不清除之前的“忽略”状态,下次发生这个信号时继续忽略)。

3,内核创建一个新的stack frame在用户stack,调用信号处理函数。

4,恢复1中保存的register context,将PC指向signal-catcher的地址(信号发生时)。

 

上述描述过程可能存在以下“异常”:

1,当进程返回到user mode之前,由于清除了u area中的signal handler field,只有再次调用signal系统调用时,才会再次扑捉到这个siganl,这是就可能存在一个竞争条件。当再次调用signal之前,相同型号又发生了,这是进程就会exit(忽略情况除外)。(参看Unix操作系统设计P207)

2,当一个进程sleep在可被中断的系统调用时,信号会造成longjmp调出睡眠,返回user mode并调用信号处理函数。当从信号处理函数返回时,进程看起来像从系统调用返回并且带有error表明此系统调用被中断了。

3,当一个进程sleep在不可被中断的系统调用时,进程将被唤醒,但是不做longjmp。即只有内核唤醒睡眠进程并运行它时,才发现忽略了此信号。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值