什么是sigaddset用于?

NeD*_*ark 7 c linux posix signals alarm

我有这个代码,我使用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();  
   } 
Run Code Online (Sandbox Code Playgroud)

我为什么需要使用它?

nos*_*nos 14

你在这做两件事:

  1. 填充一个sigset_t.sigset_t只是信号值的集合,用于各种系统调用.您可以:

    • 创建一个空的sigset_t(sigemptyset()
    • 向集合添加信号(sigaddset())
    • 删除信号到集合(sigdelset())
    • 等等...
  2. 设置信号处理程序的信号掩码.通过调用sigaction()来设置信号处理程序时,可以通过操作sigset_t sa_mask成员来实现struct sigaction.

信号处理程序的信号掩码意味着当信号处理程序正在执行时,掩码中的信号将被阻止 - 即只要它们被阻塞,这些信号就不会被处理.信号处理程序完成后,信号输入将被解除阻塞.被阻止的信号不会"丢失",当特定信号再次被阻塞时,它将被处理.

sigaddset(&act.sa_mask, SIGINT);意味着当SIGALRM处理程序的代码运行时,SIGINT信号不会发生.

另一方面,如果你注释掉sigaddset(&act.sa_mask, SIGINT);,那么你只剩下一个空的信号列表sigemptyset(&act.sa_mask);.因此,在SIGALRM处理程序函数运行时发生的任何信号都可能抢占该处理程序并执行该另一个信号的信号处理程序.

对于SIGINT,您通常不会注意到与手动测试有任何区别 - 当您的SIGALRM处理程序正在运行时,您不可能设法完全按CTRL-C,并且您的SIGALRM处理程序可能运行得足够快,如果SIGINT是,则您不会注意到稍微延迟了.


Jea*_*nès 6

信号集通过sigset_t类型进行操作.有几种操作可用于信号集:

  • 创建一个空集S via sigemptyset,S =∅
  • 将信号s添加到集合S via sigaddset,S =S∪{s}
  • 从集合中移除信号s sigdelset,S = S\{s}
  • 通过创建所有可能信号的集合sigfillset.
  • test是一个信号s在一个给定的集合S via sigismember,s∈S?

这样的一组用于不同的地方:设置新的过程信号掩码,在信号处理期间阻塞设置,请求待定信号集等.

如果您想捕获不同的信号,可能看起来某些捕获功能不能被其他信号中断,因此您可以在传送给定信号期间添加一组要阻止的信号.实际上,您决定(在取消注释时)在SIGALRM传递期间阻止SIGINT.所以你只能通过在执行处理程序期间发送SIGINT来观察这个; 这很难实现.

一个重要的例子吗?

假设SIGUSR1的处理程序修改给定的数据结构,并且SIGUSR2的处理程序使用相同的数据结构.让两个处理程序不并发是非常重要的,一个可以在另一个之后运行,但是你可能不希望在另一个交付期间被一个中断.您的代码是自并发的,即使在只有一个线程的情况下,信号也可以引导您并发.