在第10章APUE的信号中。
我对sigprocmask()
,SIG_BLOCK
和SIG_SETMASK
有一些疑问。
这些书说:“当我们阻止信号时,我们保存了旧的面具”。我的理解是:
我们声明一个newmask
类型的sigset_t
,然后sigempty(&newmask)
表示初始化新掩码,以便排除所有newmask
指向的信号,最后将SIGQUIT
添加到newmask
集中。
但我不确定以下含义。是SIG_BLOCK
指向newmask
并将sigprocmask()
指向oldmask
的信号?sigprocmask(SIG_BLOCK, &newmask, &oldmask)
“为了解除信号遮挡,我们对旧蒙版做了SIG_SETMASK
。oldmask
是包含sigset_t
的SIGQUIT
,这如何解除对信号(SIGQUIT
)的阻塞?sigprocmask(SIG_SETMASK, &oldmask, NULL)
这是完整的代码:
#include <signal.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
static void sig_quit(int signo) {
printf("caught SIGQUIT\n");
if (signal(SIGQUIT, SIG_DFL) == SIG_ERR)
printf("can't reset SIGQUIT\n");
}
int main() {
sigset_t newmask, oldmask, pendmask;
if (signal(SIGQUIT, sig_quit) == SIG_ERR)
printf("can't catch SIGQUIT\n");
/* Block SIGQUIT and save current signal mask. */
sigemptyset(&newmask);
sigaddset(&newmask, SIGQUIT);
if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
printf("SIG_BLOCK error");
sleep(5); /* SIGQUIT here will remain pending */
if (sigpending(&pendmask) < 0)
printf("sigpending error");
if (sigismember(&pendmask, SIGQUIT))
printf("\nSIGQUIT pending\n");
/* Restore signal mask which unblocks SIGQUIT. */
if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
printf("SIG_SETMASK error");
printf("SIGQUIT unblocked\n");
sleep(5); /* SIGQUIT here will terminate with core file */
return 0;
}
非常感谢!
最佳答案
我们声明一个类型为sigset_t的newmask,然后sigempty(&newmask)表示初始化该newmask,以便排除newmask指向的所有信号,最后将SIGQUIT添加到newmask集。
不完全是。 sigemptyset()
排除newmask
中的所有信号(即,它是一个空信号集)。
但我不确定以下含义。是否将新掩码指向的信号SIG_BLOCK和sigprocmask()指向旧掩码?sigprocmask(SIG_BLOCK, &newmask, &oldmask)
使用newmask
设置新的信号掩码(即,如果成功,则仅阻止SIGQUIT
),并在oldmask
中返回旧的信号掩码。
旧掩码是包含SIGQUIT的sigset_t,这如何解除对信号(SIGQUIT)的阻塞?
这不是真的。旧的信号掩码是阻止SIGQUIT
之前的信号掩码,当您阻止sigprocmask()
并将其存储在SIGQUIT
中时,信号掩码由oldmask
返回。因此,sigprocmask(SIG_SETMASK, &oldmask, NULL)
恢复旧的信号掩码(无论调用sigprocmask(SIG_BLOCK, &newmask, &oldmask)
之前的信号掩码如何)。