7.2.1 信号种类

每一种信号都给予一个符号名,对 32 位的 i386 平台而言,一个字为 32 位,因此信号有 32 种,而对 64 位的 Alpha AXP 平台而言,每个字为 64 位,因此信号最多可有 64 种。Linux定义了i38632个信号,在include/asm/signal.h中定义。表7.1给出常用的符号名、描述和它们的信号值。

      7.1              信号和其对应的值


                  

每种信号类型都有对应的信号处理程序(也叫信号的操作),就好像每个中断都有一个中断服务例程一样。大多数信号的默认操作是结束接收信号的进程;然而,一个进程通常可以请求系统采取某些代替的操作,各种代替操作是:

 

·      忽略信号。随着这一选项的设置,进程将忽略信号的出现。有两个信号  不可以被忽略:SIGKILL,它将结束进程;SIGSTOP,它是作业控制机制的一部分,将挂起作业的执行。

·      恢复信号的默认操作。

·      执行一个预先安排的信号处理函数。进程可以登记特殊的信号处理函数。当进程收到信号时,信号处理函数将像中断服务例程一样被调用,当从该信号处理函数返回时,控制被返回给主程序,并且继续正常执行。

但是,信号和中断有所不同。中断的响应和处理都发生在内核空间,而信号的响应发生在内核空间,信号处理程序的执行却发生在用户空间。

那么,什么时候检测和响应信号呢?通常发生在两种情况下:

·      当前进程由于系统调用、中断或异常而进入内核空间以后,从内核空间返回到用户空间前夕;

·      当前进程在内核中进入睡眠以后刚被唤醒的时候,由于检测到信号的存在而提前返回到用户空间。

当有信号要响应时,处理器执行路线的示意图如图7.2所示:

                     信号处理程序

用户空间

                           继续执行应用程序

          应用程序

 

 

内核空间            系统调用/中断例程

 

               7.2 信号的检测及处理流程示意图

从图中可以看出,当前进程在用户态执行的过程中,陷入系统调用或中断服务例程,于是,当前进程从用户态切换到内核态,当处理完系统调用要返回到用户态前夕,发现有信号处理程序需要执行,于是,又从内核态切换到用户态;当执行完信号处理程序后,并不是接着就在用户态执行应用程序,而是还要返回到内核态。读者会问,为什么还要返回到内核态呢,这是因为还没有真正从系统调用返回到用户态呢!于是从信号处理程序返回到内核态就是为了处理从系统调用到用户态的返回。读者能否想出更好的办法来处理这种状态的来回切换呢?