我需要澄清sigsuspend主题 . 我有一个简化的例子
sigset_t mask, oldmask;
sigemptyset (&mask);
sigaddset (&mask, SIGRTMIN+1);
sigprocmask (SIG_BLOCK, &mask, &oldmask);
sigsuspend(&oldmask);
sigprocmask (SIG_UNBLOCK, &mask, NULL);
以下是我对此的理解:
-
sigemptyset清除信号列表(掩码) - 因为它是用当前阻塞的信号(?)初始化的
-
sigaddset将SIGRTMIN 1添加到掩码中
-
sigprocmask设置要阻止掩码oldmask中的所有信号
-
sigsuspend(&oldmask)挂起线程执行,直到其中一个被阻塞的信号到达?如果我想阻止SIGRTMIN 1,是不是应该有sigsuspend(&mask)?
其次,让我们假设我在一个循环中有这样的sigsuspend并且到达了一些SIGRTMIN 1信号 . 每个信号都会继续这样的循环吗?在某种队列?
while(1){
sigsuspend(&oldmask)
printf("recieved signal");
}
这样,对于每个信号,我都会收到“收到的信号”吗?
1 回答
上一版本答案的主要部分是错误的 . 我为我的错误道歉 . 我感谢Wotim指出错误 .
POSIX对sigsuspend()的定义
POSIX标准相当清楚地描述了sigsuspend():
此外,POSIX Signal concepts说:
应用于您的代码片段
sigsuspend()
函数是旧pause()函数的现代模拟 .主要变化:两个代码块反转 .
它允许您将线程发送到睡眠状态,直到其中一个选定信号出现 . 如果您希望它在SIGRTMIN 1到达之前休眠,您可以使用:
这会阻止除SIGRTMIN 1之外的所有信号 .
如果你想睡到SIGRTMIN 1以外的信号到达,你可以使用:
这仅阻止SIGRTMIN 1 .
你的循环不会可靠地打印
Received signal
,除非你在最后添加一个换行符(可能不是那么;你可能需要fflush(stdout)
或等价物) . 但是,如果您在正常情况下阻塞了SIGRTMIN 1,然后将&oldmask
设置为仅允许SIGRTMIN 1,那么当您的代码位于sigsuspend()
时,您的信号将被可靠地传送 .您对sigprocmask()的描述不正确:
当你这样做时:
将SIGRTMIN 1添加到阻塞信号列表中(因为您使用了SIG_BLOCK且
mask
仅包含SIGRTMIN 1) .oldmask
中的输出是添加SIGRTMIN 1之前的信号掩码 . 它可能已经或可能没有包含SIGRTMIN 1.进程's signal mask is changed (if you needed to set the signal mask for a thread, you' d使用pthread_sigprocmask()
代替)从其当前值到包含SIGRTMIN 1的新值,并告诉您旧的值 .来自评论
重大变化 .
是的,这是错的 . 调用sigsuspend(&oldmask)会将线程发送到睡眠状态,直到收到oldmask中的一个信号 . oldmask的内容是在添加SIGRTMIN 1之前被阻止的信号集 .
是的,这是错的 . 调用
sigsuspend(&oldmask)
会将线程发送到睡眠状态,直到收到不在oldmask
中的信号之一 .oldmask
的内容是在添加SIGRTMIN 1之前被阻止的信号集 .以下两段被撤回而不一定被视为错误 . 我认为有一些元素两者都是事实,尽管两者都有改进的余地 .
你不使用sigsuspend()来阻止信号本身;你用它来等待一组指定的信号到达 .
如果你想忽略SIGRTMIN 1,那么你需要使用sigaction(),或者像你一样使用sigprocmask();特别阻止SIGRTMIN 1以及已被阻止的所有其他信号 .
假设'它'是sigsuspend(),那么它将阻止任何不在oldmask中的信号并等待oldmask中的一个信号到达 .
假设'it'是
sigsuspend()
,那么它将阻止oldmask
中的任何信号并等待oldmask
中的一个信号到达 .重大变化
绝对不!这将挂起线程,直到掩码中的一个信号到达 . 由于掩码中唯一的信号是SIGRTMIN 1,只有当它到达时才会返回sigsuspend() . sigprocmask()报告了在oldmask中调用之前被阻塞的内容;它根本没有修改掩码(你的变量);它确实通过添加SIGRTMIN 1来修改进程的信号掩码 .
绝对不!这将挂起线程,直到其中一个信号不在
mask
中 . 由于mask
中唯一的信号是SIGRTMIN 1,只有该信号被阻止,当任何其他信号到达时,它将被处理并且sigsuspend()
将返回 .sigprocmask()
报告了在oldmask
之前被阻止的内容;它根本没有修改mask
(你的变量);它确实通过添加SIGRTMIN 1来修改进程的信号掩码 .我强烈建议阅读或重读POSIX Signal concepts以及操纵信号处理的各种功能 . (是的,这部分是"Physician, heal thyself"的处方 . )
如果这里仍有错误,请告诉我 .