C语言 sigsud相当于sigprocmask,pause,sigprocmask的原子序列?



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

sigsuspend 函数暂时将当前阻塞集替换为掩码,然后暂停进程,直到收到其操作是运行处理程序或终止进程的信号。如果操作要终止,则进程将终止,而不会从 sigsuspend返回。如果操作是运行处理程序,则 sigsuspend 在处理程序返回后返回,将阻止的集恢复到调用 sigsuspend 时的状态。

sigsuspend 函数等效于以下函数的原子(不间断)版本:

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

据我了解,sigprocmask(SIG_BLOCK, &mask, &prev)应该导致阻塞集被掩码或,即将掩码中的信号添加到阻塞集中已有的信号中。但是代码正上方的文本(以及我查找的 sigsuspend手册页)说 sigsud"暂时用掩码替换当前阻塞集"。这听起来更像是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 行。我的直觉/理解哪里出了问题?

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

该书勘误表的此链接显示:

第8章 异常控制流


第781页。在第二段的sigsuspend描述中,第 1 行应为:
sigprocmask(SIG_SETMASK, &mask, &prev);
发表于 10/28/2015。戴夫·奥哈拉隆

最新更新