sigwaitinfo()可以等待过程信号掩码的超集吗?

时间:2017-11-28 23:13:39

标签: c signals posix

我要为sigwait()正确模仿sigwaitinfo() and sigtimedwait()Jehanne,但在{{1}选择多个信号时,我无法掌握预期的行为}}参数同时发送到等待其中一个函数的进程。

例如,第一个信号将导致sigwaitinfo返回,填充set参数。 但是第二个信号怎么样?据我所知,如果第二个信号没有被阻止(它不包含在过程信号掩码中),则进程应该接收它,中断第一个信号管理,减少使用这些功能组的优势

这让我想知道提供给这些函数的info是否必须始终是过程信号掩码的子集,或者是否还有其他我缺失的东西。

换句话说:Linux手册页指出

  

正常使用中,调用程序通过事先调用sigprocmask(2)来阻止set中的信号(这样如果这些信号在连续调用之间变为挂起,则不会发生这些信号的默认处置到sigwaitinfo()或sigtimedwait())并且不为这些信号建立处理程序。

我想知道这个"正常使用"是此API的唯一正确用法,或者有适当的用例,set参数包含的信号多于过程信号掩码。

2 个答案:

答案 0 :(得分:1)

这个小代码试图回答你的评论,似乎在Ubuntu

上按预期工作
// ctrl-c handler
void cc(int s) {
    static int count = 0;
    printf("Entering cc %d\n", ++count);
    sleep (5);
    printf("Leaving cc %d\n", count);
}

int main(int argc, char **argv) {
    signal(SIGINT, cc); // ctrl-c

    int n = 10; // leave after 10 ctrl-c
    while (n--) {
        pause();
    }
    return 0;
}
捕获

Ctrl-C 并执行cccc递增并打印一个数字,我们希望在离开函数时显示相同的数字。如果cc由于另一个 Ctrl-C 在执行完成(睡眠5)之前重新进入,我们会有类似

的内容
Entered cc 1
Entered cc 2
Leaving cc 2
Leaving cc 2

不建议在信号处理程序中执行printf之类的I / O操作,但在我们的小例子中没有共享违规,即使我们有一些 stdout 缓冲,"离开文本"如果重新进入cc,最终将与上述类似。

但这并没有发生。在cc正在休眠时按另一个 Ctrl-C 似乎确实在某处等待了第二个事件(似乎只保留了一个事件)。 sleep()可能有特殊行为?在这种情况下,无论如何,cc将在睡眠后重新输入 ,并显示上述不需要的行为。

另一个值得注意的行为是pause()。如果按下另一个 Ctrl-C ,而其中一个是"睡眠",则该2 nd 一个在同一"暂停"内执行。 (类似于while(event) { process(event); };此行为由 Ctrl-C 的数量显示,必须离开程序:应该是10,但它实际上是10 +在处理上一个键时按下键的次数。

不确定它是否适用于您的系统以及任何事件。

答案 1 :(得分:1)

我认为这取决于你的意思"正确。"

正常使用是唯一明智的用法。

允许异常使用,因为它不会对未定义的行为表示不公正。它也毫无意义,危险复杂。您的实现将有一些算法用于为sigwait两者同时调度两个待处理信号,SIG_ignoring既不阻止,也最多阻塞一个。*但是,这个过程设计正确是值得怀疑的。

*根据POSIX-1.2008的信号概念"[t]he order in which multiple, simultaneously pending signals ... are delivered to or accepted by a process is unspecified",假设非实时信号。