如果没有信号 在调用时,set是挂起的,线程应该是 暂停直到一个或多个成为 悬而未决。由set定义的信号 应该被封锁了 调用sigwait()的时间;否则,行为未定义。 sigwait()对信号的影响 集合中信号的动作是 未指定的。
这真的很模糊,pending
和block
之间的区别是什么?
关于如何在sigwait
和sigaction
之间进行选择的结论尚不清楚:
总之,当有必要时 代码运行以响应 异步信号通知 应该使用thread,sigwait() 处理信号。 Alterna- 如果实现提供了信号量,它们也可以 使用,遵循sigwait()或 来自信号处理程序 以前注册过 与sigaction()。
有人可以说sigwait
更合理吗?
答案 0 :(得分:22)
每个进程都有一个与之关联的信号掩码,它定义了阻塞的信号集。可以使用setprocmask(2)
(对于单线程代码)和pthread_sigmask(3)
(对于多线程代码)查询或设置信号掩码。
无论何时发出信号(通过kill(2)
或raise(3)
明确提出,或通过其他一些机制,如分段故障引发SIGSEGV
),都会针对当前信号检查信号面具。如果信号未被阻止,则立即对其进行操作:如果设置则调用相应的信号处理程序,否则运行默认操作(通常以异常状态退出或忽略它)。如果信号被信号掩码阻止,则信号状态设置为挂起,程序继续执行。
请考虑以下示例程序:
#include <signal.h>
#include <stdio.h>
void on_sigusr1(int sig)
{
// Note: Normally, it's not safe to call almost all library functions in a
// signal handler, since the signal may have been received in a middle of a
// call to that function.
printf("SIGUSR1 received!\n");
}
int main(void)
{
// Set a signal handler for SIGUSR1
signal(SIGUSR1, &on_sigusr1);
// At program startup, SIGUSR1 is neither blocked nor pending, so raising it
// will call the signal handler
raise(SIGUSR1);
// Now let's block SIGUSR1
sigset_t sigset;
sigemptyset(&sigset);
sigaddset(&sigset, SIGUSR1);
sigprocmask(SIG_BLOCK, &sigset, NULL);
// SIGUSR1 is now blocked, raising it will not call the signal handler
printf("About to raise SIGUSR1\n");
raise(SIGUSR1);
printf("After raising SIGUSR1\n");
// SIGUSR1 is now blocked and pending -- this call to sigwait will return
// immediately
int sig;
int result = sigwait(&sigset, &sig);
if(result == 0)
printf("sigwait got signal: %d\n", sig);
// SIGUSR1 is now no longer pending (but still blocked). Raise it again and
// unblock it
raise(SIGUSR1);
printf("About to unblock SIGUSR1\n");
sigprocmask(SIG_UNBLOCK, &sigset, NULL);
printf("Unblocked SIGUSR1\n");
return 0;
}
输出:
SIGUSR1 received!
About to raise SIGUSR1
After raising SIGUSR1
sigwait got signal: 30
About to unblock SIGUSR1
SIGUSR1 received!
Unblocked SIGUSR1
答案 1 :(得分:4)
来自signal(7)
手册页:
Signal Mask and Pending Signals A signal may be blocked, which means that it will not be delivered until it is later unblocked. Between the time when it is generated and when it is delivered a signal is said to be pending.
“等待”和“被阻止”不是相互排斥的。
同样来自signal(7)
手册页:
Synchronously Accepting a Signal Rather than asynchronously catching a signal via a signal handler, it is possible to synchronously accept the signal, that is, to block exe- cution until the signal is delivered, at which point the kernel returns information about the signal to the caller. There are two general ways to do this: * sigwaitinfo(2), sigtimedwait(2), and sigwait(3) suspend execution until one of the signals in a specified set is delivered. Each of these calls returns information about the delivered signal.
因此sigaction()
用于允许其他代码在信号挂起之前运行,而sigwait()
暂停执行该线程,直到信号挂起但被阻止。