博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux2.6信号管理
阅读量:4701 次
发布时间:2019-06-09

本文共 2276 字,大约阅读时间需要 7 分钟。

一、什么是信号

1.信号是很短的消息,可以被发送一个进程或一个进程组,用于进程间的通信

2.消息的内容通常是一个数,这个数用于标识信号

信号的接收方一定是进程,发送方可能是进程,或者内核。

信号只能发送给属于同一session以及同一个用户的进程

3.信号的种类可分为两类

(1)常规信号:编码范围1-31,如果一个常规信号被连续发送多次,会被合并成一次,即只有一个发送到接收进程

(2)实时信号:编码范围32-64,它们必须被排队,以便发送的多个信号都被接收到

(3)常规信号和实时信号,都是用队列来接收的,只是常规信号的接收队列,每个队列中最多只能有一项

(4)可以看出,每个信号对应的信号处理函数相对自己是串行的,不必是可重入的

4.子进程会继承父进程的信号处理方式

二、信号传递的过程

1.信号产生:

更新目标进程的数据结构

2.目标进程对信号的检测与反应

(1)忽略

(2)默认操作

(3)调用相应的信号处理函数

三、信号的挂起、阻塞、忽略、丢弃

1.丢弃:对于常规信号,同种类型的一次存在一个,多余的会被丢弃

2.信号阻塞:某种类型的信号被阻塞后,目标进程不会处理这个信号,直到解除阻塞后再处理(针对信号类型

3.挂起:已经产生但还没有处理的信号称为挂起信号。对于常规信号,同种类型的挂起信号一次只存在一个(针对某个具体的信号

4.忽略:目标进程已收到这个信号,并作出回应,回应的方式是不作为任何处理

四、信号产生过程

send_signal()

(1)申请一个挂起信号的数据结构

(2)把数据结构挂入挂起信号队列

(3)修改队列位掩码

(4)如果需要,唤醒进程

五、信号处理的过程

1.在中断机制中,处理器的硬件在每条指令结束进都要检测是否还有中断请求存在

信号机制是纯软件的,不能依靠硬件检测信号,只能在两个特定的时间点检测

2.对信号的检测与响应总发生于系统空间

(1)从系统空间返回到用户空间的前夕

(2)进程在内核睡眠刚被唤醒时,由于信号而提前返回到用户空间

3.进程运行于用户空间时,即使信号到达了也不会作出反应,要等到特定时刻检测到信号才会处理

4.当信号向量为SIG_IGN或SIG_DFL时,对信号的处理都在系统空间完成,无须回到用户空间

当信号向量为用户提供的信号处理程序时,需要用户空间执行,执行完再回到系统空间,然后再回到用户空间

5.执行自定义函数的过程:

do_signal() -----> handle_signal() -----> 信号处理函数

note:

信号处理函数由用户进程定义,包含在用户态代码中,在用户空间运行

handle_signal():运行在内核态

6.关于帧、函数用户、运行空间

(1)帧frame:调用一次子程序时,在栈中保存的一个层次称为一帧,包括子程序的返回地址、子程序的局部变量、调用子程序时的参数

(2)程序与子程序位于同一空间:普通的函数调用

(3)调用者在用户空间,子程序在系统空间:中断处理、异常处理、系统调用

(4)调用者在系统空间,子程序在用户空间:handle_signal()调用信号处理函数

7.从handle_signal()的系统空间 进入 信号处理函数的用户空间 的过程

要从系统空间进入用户空间执行另一段程序,就必须在系统空间准备一个新的帧,而原系统空间的帧也要保存起来

解决方法:把原系统空间帧作为信号处理程序的局部变量,保存在新的帧中

在进入用户空间执行信号处理函数之前,先准备好用户空间堆栈的帧,把原帧复制到新帧中作为局部变量保存起来,回到系统空间后再从那里复制回来

8.从信号处理函数的用户空间 返回到 handle_signal()的系统空间 的过程

用户空间进入系统空间的手段有三种:中断、异常、陷阱,系统调用是陷阱的一种

从信号处理函数返回系统空间使用的方式是系统调用

9.handle_signal() ----- 调用信号处理函数并返回

(1)在用户空间堆栈中为信号处理程序预先创建一个frame,其中包括原系统空间堆栈的frame

(2)在信号处理函数中插入系统调用sigreturn()

(3)将系统空间堆栈中的frame修改为信号处理函数所需的frame

(4)进入用户空间,开始执行信号处理函数

(5)执行信号处理函数

(6)通过系统调用figreturn()返回到系统空间

(7)从用户空间恢复系统堆栈空间的frame

(8)回到用户空间,继续执行用户程序

10.“系统空间->用户空间->系统空间->用户空间”这段过程能不能简化?

答:理论上可以。但是必须保证用户的信号处理程序对“工作现场”(SAVE_ALL所保存的部分)不能更改。

信号处理函数由用户进程定义,包含在用户态代码中,在用户空间运行,不能保证这一点。

为了系统安全,不这么做。

六、为某个信号定义信号处理函数

1.signal(int signr, sigunc *handle);

给信号值是signr的信号安装一个处理函数句柄handle

handle是函数指针

2.自定义的信号处理函数句柄只能使用一次,若要持续使用,在信号处理函数中重置自定义句柄

3.signal()的BUG:在3-(1)的复位和3-(2)的重置之间发生了信号可能会造成信号的丢失。

使用sigaction()能解决信号失去的问题

转载于:https://www.cnblogs.com/windmissing/archive/2012/03/24/2559845.html

你可能感兴趣的文章
三分法——求解凸性函数的极值问题
查看>>
HTML&CSS构建和设计网站
查看>>
快速排序+分治法
查看>>
HTML5开发之meta标签的viewport使用说明
查看>>
RF 中一条用例执行失败,终止其他用例执行
查看>>
Java web表层技术专业词汇
查看>>
Java 常用对象-Scanner类
查看>>
第八次作业
查看>>
PopupWindow计算弹出位置
查看>>
【codevs2485】七夕祭(贪心,环形纸牌均分)
查看>>
引用类型--单体内置对象
查看>>
Number()、parseInt()、parseFloat()、~~、~
查看>>
程序猿的爱情--2011-01-14
查看>>
解决stackOverflow打开慢的问题
查看>>
学习js权威指南第一站 ----- 类型、值和变量
查看>>
[RTT例程练习] 2.9 事件机制event
查看>>
g第十四周,十五周作业
查看>>
opencv_haar分类器的训练
查看>>
[原创]cocos2d-x + Lua接入iOS原生SDK的实现方案
查看>>
用JavaScript实现CheckBox的全选取消反选,及遮罩层中添加内容
查看>>