1. 一、什么是信号

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

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

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

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

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

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

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

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

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

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

2. 二、信号传递的过程

1.信号产生:

更新目标进程的数据结构

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

(1)忽略

(2)默认操作

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

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

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

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

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

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

4. 四、信号产生过程

send_signal()

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

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

(3)修改队列位掩码

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

5. 五、信号处理的过程

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所保存的部分)不能更改。

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

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

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

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

handle是函数指针

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

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

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

results matching ""

    No results matching ""