++++++APUE读书笔记-10信号-08可靠的信号技术以及相应的语义++++++
8、可靠的信号技术以及相应的语义
================================================
在我们讨论信号的时候,需要知道一些事情:首先,当导致信号的事件发生的时候,就会给进程产生相应的信号(或者信号发送给进程),这个事件可能是硬件错误(例如:除以0),软件错误(例如时钟信号),终端发起的信号,或者是使用kill发起的信号.当产生信号的时候,内核经常会给进程的进程表设置一个标记。
当调用了信号相应的动作,我们就说信号已经被发送(deliverd)给进程了。在产生信号(generate)和发送信号(delivered)之间的时间,被称作信号的提交(pending)。
进程可以阻塞发送给它的信号.如果发送给一个进程的信号被阻塞了,并且这个信号的处理动作是默认的动作或者捕获信号,那么这个进程的信号会保持提交的状态,直到发生如下:a)将信号的阻塞取消 b)改变信号的处理动作以忽略信号.系统在信号被发送的时候而不是产生的时候来确定对一个阻塞的信号做什么。这样,进程可以在信号被发送给它之前,改变信号处理动作的行为。进程可以调用函数sigpending来决定哪些信号被阻塞或者提交。
如果被阻塞的信号在进程取消对它的阻塞之前发生了多次会怎么样?POSIX.1允许系统给进程提交多次信号.如果系统发送信号的次数超过了一次,我们就说那个信号被排队了。然而许多unix系统不支持信号的排队,除非它们POSIX.1的实时扩展。UNIX系统内核只支持信号被发送给进程一次。
SVR2的man手册说SIGCLD信号在进程处理它的处理函数的时候会被排队。虽然这个在概念上面是正确的,但是实际的实现上面却不是这样的。相反,信号会被内核重新产生,就像我们在前面说的那样。在SVR3中,man手册修改了,并且示意SIGCLD信号在进程处理它的处理函数的时候被忽略。SVR4手册把进程处理SIGCLD处理函数时候,又产生SIGCLD究竟会发生什么的相关内容删除了。在AT&T的SVR4的sigaction的man手册中声明SA_SIGINFO导致信号排队的时候是可靠的。这个是错误的!很明显,这个特性是内核中实现的特性,但是它并没有在SVR4中被启用。很奇怪的是,SVID没有阐述相同的可靠排队的内容。
当不止一个信号要被发送给一个进程的时候会发生什么?POSIX.1没有指定发送给进程的信号的次序,但是POSIX.1提供了一个建议:那就是和进程当前状态相关的信号,先于其他信号被发送给进程(SIGSEGV就是这样的信号)。
每个进程都有一个signal mask,它定义了当前被阻塞发送给进程的信号的集合。我们可以认为这个mask的每一个位代表一个信号,如果某个信号的对应的位被打开了,那么这个信号当前就会被阻塞。一个进程可以通过调用sigprocmask检查和改变它当前的signal mask,我们后面有说明。
因为信号的数目可能会超过整数的位数,所以POSIX.1定义了数据类型sigset_t来保存一个信号集合,用这个数据结构保存信号的集合。例如signal mask就存放在这些集合中的其中一个。我们后面会描述5个操作信号集合的函数。
参考:
阅读(612) | 评论(1) | 转发(0) |