10.8 可靠信号术语以及语义

我们需要定义一些术语来继续信号的讨论,首先,信号是在造成信号的事件出现的时候由进程产生或者被发送到进程的,该事件可能是硬件错误(比如说除零错误),软件条件(比如说alarm设置的时间达到),或者是终端信号,或者是kill函数的调用,当信号产生的时候,内核通常在进程表中设置一些标志。

我们所说的”信号被发送到一个进程”是在进程准备执行信号处理函数的时候,在信号生成和被发送之间的时候,信号被称为pending.

进程可以选择阻塞信号的发送,如果一个被阻塞的信号产生,那么信号就会保持挂起状态直到如下条件出现:
(a). 不在阻塞信号;
(b). 改变信号的处理为忽略信号;
系统是在信号被发送的时候决定执行什么操作的,而不是在信号产生的时候,这允许程序在信号被发送前对信号的处理方式进行修改,函数sigpending可以被进程调用用于决定哪个信号被阻塞或者挂起。

如果在被阻塞的信号被接触阻塞之前多次产生的话怎么办呢?POSIX.1允许系统发送该信号一次或者是多次。如果系统发送该信号多次,我们是信号被排队了(queued),许多UNIX系统并不会对信号进行排队,而是简单地只发送一次信号,除非它们支持POSIX.1的实时扩展。

with SUSv4,实时信号功能从实时扩展中移动到了基本标准中,随着时间的推移,许多系统将会支持信号排队,即使它们不支持实时扩展,我们将在10.20中讨论queueing signals.
SVR2的手册中说SIGCLD信号在进程正在执行SIGCLD的信号处理函数的时候是排队的,虽然这在概念上可能是真的,但是其实际的实现是不一致的,信号实际上是在内核中重新生成的,关于这一点将在10.7中进行介绍,在SVR3中,手册进行了修改,表示当SIGCLD的信号处理函数正在被执行的时候SIGCLD信号将被忽略,而到了SVR4中,手册将SIGCLD信号在其处理函数正在被执行的时候出现将会发生什么的说明完全移除。
SVR4中的函数sigaction(2)用户手册声明SA_SIGINFO标识可以让信号可靠地排队,这是错误的,看起来,该特性只是在内核内被部分实现了,但是在SVR4中并没有使能,奇怪的是,SVID(System V Interface definition)不在对于上述可靠排队的事情执行相同的声明。

当多个信号准备好发往一个进程会发生什么呢?POSIX.1并没有指定哪一个信号将被发送到进程,而POSIX.1的Rationale(基本原理)给出了建议:与当前进程状态有关的信号应该在其他信号之前发送。比如说SIGSEGV就是其中一个与进程有关的信号。

每一个进程有一个信号掩码,该掩码定义了当前被阻塞发送的信号的集合,我们可以认为每一个信号对应一个bit,如果对于给定信号该bit是打开的,该信号当前就是被阻塞的,进程可以调用函数sigprocmask来检查以及改变当前信号掩码,关于该函数我们将在10.12节中进行讲述。

因为信号的数量可能超过一个整形变量的bit数,POSIX.1定义了一个新的数据结构,称为sigset_t,该结构用于保存一个信号集,信号掩码就是这些信号集中的一个,我们将在10.11中讲述五个可以操作信号集的五个函数。





posted @ 2016-05-22 23:31  U201013687  阅读(190)  评论(0编辑  收藏  举报