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

  • 相关阅读:
    [编写高质量代码:改善java程序的151个建议]建议72 生成字列表后不要再操作原列表
    [编写高质量代码:改善java程序的151个建议]建议71 推荐使用subList处理局部列表
    [编写高质量代码:改善java程序的151个建议]建议70 子列表只是原列表的一个视图
    程序员的简历到底该怎么写?(转)
    SQL数据库数据优化SQL优化总结( 百万级数据库优化方案)
    sqlserver的四种分页方式
    sql server中截取字符串的常用函数(自己经常到用的时候想不起来所以拿到这里)
    SQL之存储过程详细介绍及语法(篇幅比较长慢慢看)
    超经典SQL练习题,做完这些你的SQL就过关了
    SqlServer 数据库引擎优化顾问优化数据库(消耗内存很大)
  • 原文地址:https://www.cnblogs.com/windmissing/p/2559845.html
Copyright © 2011-2022 走看看