zoukankan      html  css  js  c++  java
  • Linux2.6信号管理

    一、什么是信号

    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()能解决信号失去的问题

  • 相关阅读:
    第二十一章流 1流的操作 简单
    第二十章友元类与嵌套类 1友元类 简单
    第十九章 19 利用私有继承来实现代码重用 简单
    第二十章友元类与嵌套类 2嵌套类 简单
    第十九章 8链表类Node 简单
    第二十一章流 3用cin输入 简单
    第十九章 10 图书 药品管理系统 简单
    第十九章 11图书 药品管理系统 简单
    第二十一章流 4文件的输入和输出 简单
    第十九章 12 什么时候使用私有继承,什么时候使用包含 简单
  • 原文地址:https://www.cnblogs.com/windmissing/p/2559845.html
Copyright © 2011-2022 走看看