日期:2014-05-16  浏览次数:20708 次

(莱昂氏unix源代码分析导读-25) signal(下)

                                                 By cszhao1980

下面来看一下信号的处理过程。

首先,进程需要不时的检查自己是否收到signal,此时需要调用issig()函数,该函数会返回

进程此时收到的signalsignal type(如果没有signal,或忽略此signal,则返回0):

3991: issig()

3992: {

3993:    register n;

3994:    register struct proc *p;

3995:

3996:    p = u.u_procp;

3997:    if(n = p->p_sig) {

3998:       if (p->p_flag&STRC) {       /进程处于trace模式,以后再详细解释

3999:          stop();

4000:          if ((n = p->p_sig) == 0)

4001:             return(0);

4002:       }

4003:       if((u.u_signal[n]&1) == 0)  /偶数表示,不可忽略此信号,故返回signal type

4004:           return(n);

4005:    }

4006:    return(0);

4007: }

 

当确定有收到信号后,会调用psig()进行处理:

(1)         如果有指定信号处理程序地址,则执行之;

(2)         否则,结束进程。

 

听起来很简单,但令人深感意外的是,pisg()程序比想象中复杂的多。

这是“信号处理程序”身处user空间,而目前,进程在kernel态。

 

在讲解之前,首先补充一点知识:psig()函数只被中断/陷入处理程序调用,

因此,如果调用到了该函数,证明此时肯定发生了一次中断/陷入。