sigaddset 是做啥用的?
Posted
技术标签:
【中文标题】sigaddset 是做啥用的?【英文标题】:What is sigaddset used for?sigaddset 是做什么用的? 【发布时间】:2014-12-01 11:37:41 【问题描述】:我有这段代码,我使用 sigaddset 和 sigaction。但是,如果我评论 segaddset 结果是一样的
struct sigaction act;
act.sa_handler = process_alarm;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
//sigaddset(&act.sa_mask, SIGINT);
sigaction(SIGALRM, &act, NULL);
for(;;)
alarm(3);
pause();
为什么我需要使用它?
【问题讨论】:
您在运行程序时是否尝试按CTRL + C
并注释掉sigaddset()
?
@SouravGhosh 是的,但正如在其他答案中指出的那样,警报处理程序会快速运行以注意到其影响。在处理程序中添加sleep(10)
,我可以看到区别:)
【参考方案1】:
你在这里做两件事:
填充sigset_t
。 sigset_t 只是信号值的集合,用于各种系统调用。你可以:
为信号处理程序设置信号掩码。当您通过调用 sigaction() 设置信号处理程序时,您可以通过操作 struct sigaction
的 sigset_t sa_mask
成员来做到这一点。
信号处理程序的信号掩码意味着当信号处理程序正在执行时,掩码中的信号将被阻塞 - 即,只要它们被阻塞,这些信号就不会被处理。当信号处理程序完成后,信号输入将被解除阻塞。 被阻塞的信号不会“丢失”,它将在该特定信号再次被解除阻塞时处理。
sigaddset(&act.sa_mask, SIGINT);
表示当SIGALRM
处理程序的代码正在运行时,不会出现 SIGINT 信号。
另一方面,如果您注释掉sigaddset(&act.sa_mask, SIGINT);
,您将只剩下一个使用sigemptyset(&act.sa_mask);
创建的信号的空列表。因此,在 SIGALRM 处理程序函数运行时发生的任何信号都可能抢占该处理程序并为该其他信号执行信号处理程序。
对于 SIGINT,您通常不会注意到与手动测试有任何区别 - 您不太可能在您的 SIGALRM 处理程序正在运行时准确地按下 CTRL-C,并且您的 SIGALRM 处理程序可能运行得足够快,以至于您不会注意到如果SIGINT 稍有延迟。
【讨论】:
【参考方案2】:信号集通过sigset_t
类型进行操作。有几种操作可用于信号集:
sigemptyset
创建一个空集S,S=∅
通过sigaddset
将信号s添加到集合S中,S=S∪s
通过sigdelset
,S=S\s从集合中删除信号s
通过sigfillset
创建所有可能信号的集合。
test is a signal s is in a given set S via sigismember
, s∈S?
这样的集合用在不同的地方:设置新的进程信号掩码、信号处理期间的阻塞集合、请求待处理信号的集合等。
如果要捕获不同的信号,可能看起来某些捕获函数不能被其他函数中断,因此您可以在给定信号的传递过程中添加一组要阻塞的信号。您实际上决定(当未注释时)在 SIGALRM 交付期间阻止 SIGINT。因此,您只能通过在处理程序执行期间发送 SIGINT 来观察这一点;这很难实现。
一个重要的例子?
假设 SIGUSR1 的处理程序修改给定的数据结构,而 SIGUSR2 的处理程序使用相同的数据结构。使两个处理程序不并发非常重要,一个可以在另一个之后运行,但您可能不希望在另一个交付期间被一个中断。您的代码是自并发的,也就是说即使在只有一个线程的情况下,信号也可以引导您实现并发。
【讨论】:
【参考方案3】:sigaddset 用于将相应的信号掩码添加到该 sigset_t 变量。
在 sigaction 中,它不是必需的。当您使用 sigprocmask 时,您可以使用它来阻止我们在该变量中提到的信号。
【讨论】:
以上是关于sigaddset 是做啥用的?的主要内容,如果未能解决你的问题,请参考以下文章
maven.multiModuleProjectDirectory 是做啥用的?
cursor.setNotificationUri() 是做啥用的?