c - sigsuspend 等价于 sigprocmask、pause、sigprocmask 的原子系列?

标签 c exception signals signal-handling multiple-processes

我正在阅读有关 Linux x86-64 系统的信号/ECF 的教科书章节(CS:APP,第 3 版,第 8 章,第 781 页),并遇到了这个:

The sigsuspend function temporarily replaces the current blocked set with mask and then suspends the process until the receipt of a signal whose action is either to run a handler or to terminate the process. If the action is to terminate, then the process terminates without returning from sigsuspend. If the action is to run a handler, then sigsuspend returns after the handler returns, restoring the blocked set to its state when sigsuspend was called.

The sigsuspend function is equivalent to an atomic (uninterruptible) version of the following:

1       sigprocmask(SIG_BLOCK, &mask, &prev);
2       pause();
3       sigprocmask(SIG_SETMASK, &prev, NULL);


据我了解,sigprocmask(SIG_BLOCK, &mask, &prev)应该导致阻塞集合与掩码进行或运算,即将掩码中的信号添加到阻塞集合中的信号中。但是代码正上方的文本(以及我查过的 sigsuspend 手册页)说 sigsuspend “暂时用掩码替换了当前的阻塞集”。这听起来更像是 sigprocmask(SIG_SETMASK, &mask, &prev)对我来说,阻塞集只是设置为等于掩码中的信号。
那么为什么是 sigsuspend(&mask)相当于上面的代码(第 1-3 行)而不是下面的代码(第 4-6 行)?我的直觉和/或对 signal.h 函数的理解哪里出了问题?
4       sigprocmask(SIG_SETMASK, &mask, &prev);
5       pause();
6       sigprocmask(SIG_SETMASK, &prev, NULL);

如果我不清楚,让我问一个具体的问题(它可能更好地解释我的直觉)。假设当前阻塞集编码 SIGCHLD,而 sigset_t 掩码编码 SIGINT。我打电话sigsuspend(&mask) .无论哪种代码解释是正确的(第 1-3 行或第 4-6 行),在调用 sigsuspend 之后传递的 SIGINT 信号都将被阻塞/不会唤醒进程。但是,如果在调用 sigsuspend 之后立即传递一个 SIGCHLD 信号呢?进程会唤醒/接收信号吗?我的直觉是第 1-3 行会阻塞 SIGCHLD 而第 4-6 行不会,所以很明显第 1-3 行和第 4-6 行是不等价的。但是我的直觉还说 sigsuspend 不应该阻塞 SIGCHLD 因为它不在掩码中,所以第 4-6 行是正确的,如果在这种情况下第 4-6 行等效于 sigsuspend,则 sigsuspend 不能等效于第 1- 3.我的直觉/理解哪里出了问题?

最佳答案

关于技术书籍(尤其是教科书)的事情是,您应该始终了解是否有可用的勘误表。

link该书的勘误表显示:

Chapter 8: Exceptional Control Flow
...
...
p. 781. In the description of sigsuspend in the second paragraph, line 1 should be:
sigprocmask(SIG_SETMASK, &mask, &prev);
Posted 10/28/2015. Dave O'Hallaron

关于c - sigsuspend 等价于 sigprocmask、pause、sigprocmask 的原子系列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55739801/

相关文章:

linux - 应用程序可能以何种方式死亡?

c++ - 如何使用按位运算符提取整数中的数字

c - C 编译器如何处理后增量 (i++),内存明智?

linux - 为什么我的信号处理程序不工作?

java - Spring Rest Controller 异常处理

unit-testing - Unity 中的单元测试 - 获取 InvalidCastException - 为什么?以及如何解决?

c - 是否可以同时使用自定义 sigaction 信号处理程序和 pthread_sigmask?

c - 将外部变量重新定义为静态时没有错误

C 需要关于 char connect 和 split 函数的建议

java - 在 AsyncTask 中捕获未处理异常的设计模式