ITPub博客

首页 > 自动化运维 > > linux 2.4内核之信号(一)

linux 2.4内核之信号(一)

作者:飘絮絮絮丶 时间:2020-05-21 14:55:08 0 删除 编辑

linux 2.4内核之信号(一)

这两天看信号,略有所感.记下以示.

限于规模.只是略讲以及自己困惑过的地方.由于描述能力和理解力

错误的地方还请多谅解和指正

begin:

1.信号的许多基础问题我就不说了(当然是我认为的).这里主要讲下几个比较搞的概念

信号屏蔽: 主要区分好block和sa_mask就好,信号有两个地方屏蔽,第一是进程的task_struct中有一个

block,这是一直起作用的.还有就是设置信号处理程序时的sigaction结构的sa_mask.kill,stop信号不允许

被屏蔽.当然也不能设置处理函数. 在信号发送时,要将一个接收位图相关的位置1,并将信号挂入一个队列.

如果接收进程对应该信号没有被block,则唤醒接收进程

2. 信号接收位图:

当接收到信号后,要将对应的信号位图置1.被处理后再置回0,但由于由于在接收信号和处理信号之间还可能有

信号被接收,即存在时间窗口,信号可能被合并.所以引入了一个struct sigqueue.当发送信号时,就将

pending对应的位图置1.并加入sigqueue.这样才能保证记录信号的次数.但是对于以前老的机制(信号值小于

SIGRTMIN的),内核只将其抽取构造出相应结构,挂入sigqueue一次.所以信号值小于SIGRTMIN的信号,在处理

时,并不能记录在时间窗口中发生的次数,还是会合并掉

3. do_signal()

进程检测信号存在的时机.当(1)从系统调用返回,中断异常处理返回时,会检测信号task struct ->

sigpending.(2)当进程被唤醒时(必定是在系统调用中),如果发现有信号等待就提前从系统调用中返回.

这里主要讲一下是如何处理接收位图的.因为一开始这里没弄清楚(主要是忽略了dequeue_signal的代码,因为

情景分析里面没讲).具体实现就是在dequeue_signal()中,这个函数先参照block位图(看dequeue_signal

(t->blocked, &info);传了blocked参数),再根据进程的接收位图找到要处理的信号(即设置了位1)然后使其

脱队,再进行处理(实际上这个时候还没处理,还在系统空间为返回做准备,没切换到用户空间.在do_signal()

返回后才切换.).如果没有设置SA_NODEFER属性,则当前要处理的信号被自动屏蔽(是block).即通过

sigaddset(t->blocked,sig);实现,具体在内核和用户空间切换的代码还没看.反正切换到用户空间处理后再

通过一个系统调用回到系统空间.如果还有信号则继续处理.(不要问为什么不能一次性处理完,要在系统空间和

用户换来换去.记住处理程序在用户空间.)

4.最后注意sigorsets(t->blocked,t->blocked,&ka->sa.sa_mask); 从用户的信号屏蔽码刷新阻塞信

号集.找到了这个.相信可以区分一开始讲的进程的block还有sigaction结构的sa_mask(它其实也靠进程的

block位图实现屏蔽.) 还有一个接收位图了吧..虽然它们的类型都是sigset_t;

补充一下,使信号脱队时,只有判断所有同种信号都脱队完时,才能清接收位图的标志位。

这在collect_signal()函数中可以找到具体代码

文章来源CU社区:linux 2.4内核之信号(一)

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69946831/viewspace-3141125/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-09-09

  • 博文量
    2646
  • 访问量
    42234