为什么需要在 sigwait() 之前阻止信号?

为什么需要在 sigwait() 之前阻止信号?

APUE第12章第454页中提到:

为了避免错误的行为,线程必须阻塞它正在等待的信号......

标准中也有类似的说法:

信号定义为在调用时应已被阻止sigwait();否则,行为是未定义的。

这些文本中讨论了哪些错误/未定义的行为?我在标准中找不到基本原理或应用程序用法,并且我很难理解书中的解释:

如果信号没有被阻塞...,则打开一个计时窗口,其中一个信号可以在线程完成对 的调用之前传递到线程sigwait

答案1

这是来自qnx 文档,但它与所有 Unix 和类 Unix 发行版相关:

在调用 sigwait() 之前,应阻止 set 定义的信号。如果您不阻止它们,则会出现竞争条件,因为可以在进行调用之前传递信号,从而导致调用被阻止,而您可能不希望它这样做。

答案2

这个答案首先将读者带入标准发展的历史视角,然后将读者的注意力引向标准的具体文本,以解释该要求的原因。

在 XPG 第 3 期中,引入了sigaction以及sig*setsigismembersigpendingsigprocmasksigsuspend,以与 POSIX.1-1988 标准保持一致。其中,sigaction提供了最全面和一致的接口来指定信号配置;sigpendingsigprocmasksigsuspend提供了对信号进行细粒度响应的方法。

在 XPG 第 4 期(当前最古老的数字形式)中,引入了、sigaltstack、 。最新的标准没有说明它们来自哪里,只是说它们几乎已经过时了,因为它们只能在单线程进程中工作。sig{hold,ignore,pause,relse,set}siginterruptsigaltstack

在 XPG 第 5 期(单一 Unix 规范版本 2)中,引入了pthread_sigmask、 、sigqueuesigtimedwaitsigwaitinfo,以便与 POSIX 实时和线程扩展保持一致。sigwait

现在,重要的是要查看该标准中的其他两个地方。

系统接口一般信息卷,信号概念第一名:

...信号可以被“阻止”传递到线程。如果与阻塞信号相关的操作不是忽略该信号,并且如果该信号是为线程生成的,则该信号应保持挂起状态,直到它被解除阻塞为止,当它被选择并通过调用返回时,它会被接受该sigwait()功能或与其关联的操作被设置为忽略该信号。

sigwait显然,除了可能最终忽略信号之外,信号可以有两种到达进程/线程的方式 - 被解除阻塞,或被(及其兄弟姐妹,例如sigtimedwaitsigwaitinfo)接受

第二名sigaction

在进程内对同一信号同时使用 sigaction() 和 sigwait() 函数的结果未指定。

显然,sigwait它被设想为处理信号的第二种方法。

sigtimedwait和接口的基本原理中的以下文本进一步证实了这一点sigwaitinfo

sigwait 函数为线程提供同步机制来等待异步生成的信号。

相关内容