• Minix3信号处理分析


    进程的信号处理的相关结构

    PM中存放着所有进程的进程描述符,在一个进程描述符中,有一个指针,指向一个sigaction结构二维数组中的一项,表示这个进程所有信号的操作.一个sigaction结构包含信号处理函数的起始地址,执行期间需要屏蔽的信号,以及表示如何处理信号的标志

     

    代表一个进程对单个信号操作的Sigaction结构如下

    进程描述符结构为mproc如下

    信号处理流程

    1、寻找接收信号的进程

    进程A要发送信号,需要传入一个proc_id,指明接收信号的进程。PM中有一个数组,存放着所有进程的进程描述符,PM会遍历该数组,根据proc_id和进程A的相关信息去找到接收信号的进程。

    进程描述符的mp_pid,mp_procgrp:

     

             proc_id>0时,把信号发送到其mp_pid等于proc_id的进程

             proc_id=0时,把信号发送到mp_procgrp等于A mp_procgrp的进程

             proc_id=-1时,把信号发送到所有进程,除了swapper,unit和当前进程

             proc_id<-1时,把信号发生到mp_procgrp等于-proc_id的所有进程

             同时在决定进程能否发送信号的时候有一些条件,如检查真实uid和有效uid等

    2、查看接收信号的进程对于信号的处理方式

    具体位图查看末尾mproc结构

    转化为信号

    发送信号给系统进程

    忽略信号:什么都不做

    Ignore位图被置位

    悬挂信号:将信号加入pending位图

    1、mask位图置位

    2、进程处于等待调用状态,并且停止等待失败

    3、被跟踪

    检查点:在任何改变sigmask位图之后,调用sigreturn之后

    捕获信号:做进一步的信号处理,重新设置栈的内容

    Catch位图被置位

    3、捕获信号

    将sigaction中的各种信息和sigreturn函数的地址传递给内核。内核去重新设置栈和寄存器内容,让进程再次运行时执行信号处理函数,并且信号处理函数执行完成之后执行sigreturn,进程返回到信号处理函数执行的状态

     

    信号相关调用

    Sigaction调用:改变进程的某一个信号操作,或是获取进程的某一个操作

    根据一个进程的进程描述符中的指针,找到代表目的进程该信号操作的sigaction结构。直接返回或是替换

     

    Sigprocmask调用:改变进程的屏蔽信号

             对进程描述符上代表屏蔽信号的sigmask位图进行替换,替换完成之后要检查,看是否有非屏蔽的挂起信号

    Kill调用:向另一个进程发送信号

             完整执行上述信号处理流程

    Sigsuspend调用:悬挂进程,等待某些信号唤醒

             将进程原屏蔽位图sigmask保存到sigmask2,将sigmask置为我们在挂起时需要屏蔽的信号位图,然后暂停。同意,再改变了屏蔽信号的位图之后需要检查,看是否有非屏蔽的挂起信号

     

    Sigpending调用:得到进程当前屏蔽的信号

             返回当前进程的sigmask位图

    Sigreturn调用:在信号处理后恢复进程状态到信号处理之前

    struct sigaction

    {

    handler_t     sa_handler;//信号处理函数指针

    sigset_t      sa_mask;//信号处理函数运行时需要屏蔽的信号

    int           sa_flags;//怎样处理信号的一个标志集

    };

    mproc{

             ...

             sigset_t mp_ignore;           /* 1 means ignore the signal, 0 means don't*/

             sigset_t mp_catch;            /* 1 means catch the signal, 0 means don't */

            sigset_t mp_sigmask;          /* signals to be blocked */

             sigset_t mp_sigmask2;         /* saved copy of mp_sigmask */

            sigset_t mp_sigpending;       /* pending signals to be handled */

             sigset_t mp_ksigpending;      /* bitmap for pending signals from the kernel */

            sigset_t mp_sigtrace;         /* signals to hand to tracer first */

            ixfer_sigaction *mp_sigact;   /* as in sigaction(2), pointer into mpsigact     */

             vir_bytes mp_sigreturn;       /* address of C library __sigreturn function     */

             unsigned mp_flags;            /* flag bits */

             ...

    }

  • 相关阅读:
    DM9000网卡驱动接受数据从中断方式改成NAPI方式小记
    20130317
    c++版本新浪微博sdk库交叉编译
    新年预期小记
    arm+linux嵌入式系统的终端显示中文乱码解决
    记transmission下载sd卡支持不佳问题
    嵌入式linux自动登录
    SevenArmsSeries.Repositories
    Mybatis开启二级缓存(全局缓存)的方法
    Spring学习之动态代理的简单实现
  • 原文地址:https://www.cnblogs.com/likaiming/p/7814431.html
Copyright © 2020-2023  润新知