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 */

         ...

}

原文地址:https://www.cnblogs.com/likaiming/p/7814431.html