关于sigwait()的模棱两可的描述
如果在调用时没有设置信号挂起,则线程将被挂起,直到一个或多个挂起。set定义的信号在调用sigwait()时应已被阻止;否则,行为是不确定的。sigwait()对set中的信号的信号动作的影响未指定。
这真的很模棱两可,pending
和block
这里有什么区别?
而其对如何进行选择的结论sigwait
并sigaction
不能完全清楚:
总之,当需要运行代码以响应异步信号来通知线程时,应使用sigwait()处理该信号。或者,如果实现提供信号量,则也可以在sigwait()之后或从先前在sigaction()中注册的信号处理例程中使用它们。
有人可以说出sigwait
更理性的理由吗?
回答:
每个进程都有与其相关的所谓 信号屏蔽 ,它定义了被 阻塞
的信号集。可以查询信号掩码或使用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
以上是 关于sigwait()的模棱两可的描述 的全部内容, 来源链接: utcz.com/qa/413042.html