分类: 系统运维
2012-03-30 19:13:15
我们需要一些贯穿我们信号讨论的术语。首先,当导致信号的事件发生时,为一个进程产生(或发送给一个进程)信号。这个事件可以是硬件异常(例如,被 0除),一个软件情况(比如,一个alarm计时器过期),一个终端产生的信号,或一个kill函数的调用。当信号产生时,内核通常在进程表里以一些形式 设置一个标志。
我们说一个信号被分发给一个进程,当进程的动作被采纳时。在一个信号产生和它被分发之间,这个信号称为待定的(pending)。
一个进程有阻塞一个信号分发的选项。如果一个被阻塞的信号为一个进程产生,而如果这个信号的动作是默认动作或捕获,那么这个信号为进程保持待定,直到进程 a、反阻塞这个信号,或b、改变动作为忽略这个信号。系统决定当信号分发时,而不是当它被产生时,如何处理一个阻塞的信号。这允许进程在这个信号分发前为 它改变改变动作。sigpending函数(10.13节)可以被一个进程调用来决定哪些函数被阻塞和待定。
如果一个阻塞的信号在进程反阻 塞它前被产生了不只一次会发生什么呢?POSIX.1允许系统分发这个信号一次或者多次。如果系统分发这个信号多于一次,我们称这个信号被排队。然而,多 数UNIX系统,不会排队信号,除非它们支持POSIX.1的实现扩展。相反,UNIX内核简单地分发这个信号一次。
SVR2的手册页声明 SIGCLD信号被排队,当进程正在执行它的SIGCLD信号处理器时。尽管这可能在概念层次上是真的,但是真实实现却不同。相同,这个信号被内核重新产 生,如我们在10.7节描述的那样。在SVR3,手册被修改为指明当进程正在执行SIGCLD的信号处理器时SIGCLD信号被忽略。SVR4删除了任何 关于当一个进程正在执行SIGCLD的信号处理器时发生什么的内容。
SVR4的在AT&T[1990e]的sigaction手册页声明SA_SIGINFO标志导致信号被可靠排队。这是错的。显然,这个特性在内核里是部分实现的,但是不在SVR4里启用。很奇怪地,SVID没有做出可靠排队的声明。
如果多于一个的信号准备分发给一个进程会发生什么呢?POSIX.1没有规定信号分发给进程的顺序。然而,POSIX.1的Rationale确实建议,与进程当前状态相关的信号要在其它信号之前分发。(SIGSEGV是这样一个信号)。
每个进程有一个信号掩码,定义了当前阻塞的信号集。我们可以把这个掩码视为每个位对应每个可能的信号。如果对于给定信号的位是打开的,那么这个信号当前被阻塞。一个进程可以检查和改变当前的信号掩码,通过调用sigprocmask,10.12节。
既然信号的数量可能超过一个整型的位数,那POSIX.1定义了一个数据类型,称为sigset_t,来存储一个信号集。例如,信号掩码被存储在这些信号集的某一个里。我们在10.11节描述操作信号集的5个函数。