简体   繁体   English

什么是sigaddset用于?

[英]What is sigaddset used for?

I have this code where I use sigaddset and sigaction. 我有这个代码,我使用sigaddset和sigaction。 However if I comment segaddset the result is the same 但是如果我评论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();  
   } 

Why do I need to use it? 我为什么需要使用它?

You are doing 2 things here: 你在这做两件事:

  1. Populating a sigset_t . sigset_t A sigset_t is just a collection of values for signals, and are used in various system calls. sigset_t只是信号值的集合,用于各种系统调用。 You can: 您可以:

    • Create an empty sigset_t (sigemptyset() 创建一个空的sigset_t(sigemptyset()
    • Add a signal to the set (sigaddset()) 向集合添加信号(sigaddset())
    • Remove a signal to the set (sigdelset()) 删除信号到集合(sigdelset())
    • etc... 等等...
  2. Setting the signal mask for the signal handler. 设置信号处理程序的信号掩码。 You do that by manipulating the sigset_t sa_mask member of the struct sigaction when you set up a signal handler in with a call to sigaction(). 当您通过调用sigaction()设置信号处理程序时,可以通过操作struct sigactionsigset_t sa_mask成员来实现。

The signal mask of a signal handler means that while the signal handler is executing, the signals that are in the mask will be blocked - ie those signals will not be handled as long as they are blocked. 信号处理程序的信号掩码意味着当信号处理程序正在执行时,掩码中的信号将被阻止 - 即只要它们被阻塞,这些信号就不会被处理。 When the signal handler are finished, the signals in will be unblocked. 信号处理程序完成后,信号输入将被解除阻塞。 A signal that is blocked isn't "lost", it will be handled when that particular signal is unblocked again. 被阻止的信号不会“丢失”,当特定信号再次被阻塞时,它将被处理。

The sigaddset(&act.sa_mask, SIGINT); sigaddset(&act.sa_mask, SIGINT); means the the SIGINT signal cannot occur while the code for the SIGALRM handler is running. 表示SIGALRM处理程序的代码运行时不会发生SIGINT信号。

On the other hand, if you comment out sigaddset(&act.sa_mask, SIGINT); 另一方面,如果你注释掉sigaddset(&act.sa_mask, SIGINT); , you're left with just an empty list of signals created with sigemptyset(&act.sa_mask); ,你只剩下一个用sigemptyset(&act.sa_mask);创建的空信号列表sigemptyset(&act.sa_mask); . So any signals that occur while the SIGALRM handler function is running might preempt that handler and execute the signal handler for that other signal. 因此,在SIGALRM处理程序函数运行时发生的任何信号都可能抢占该处理程序并执行该另一个信号的信号处理程序。

For a SIGINT, you would normally not notice any difference with manual testing - it's unlikely you manage to hit CTRL-C exactly when your handler for SIGALRM is running, and your SIGALRM handler probably runs quickly enough that you would not notice if the SIGINT was slightly delayed. 对于SIGINT,您通常不会注意到与手动测试有任何区别 - 当您的SIGALRM处理程序正在运行时,您不可能设法完全按CTRL-C,并且您的SIGALRM处理程序可能运行得足够快,如果SIGINT是,则您不会注意到稍微延迟了。

Signals sets are manipulated via sigset_t type. 信号集通过sigset_t类型进行操作。 Several operations are available for signals sets: 有几种操作可用于信号集:

  • create an empty set S via sigemptyset , S=∅ 通过sigemptyset创建一个空集S,S =∅
  • add a signal s to a set S via sigaddset , S=S∪{s} 通过sigaddset将信号s添加到集合S,S =S∪{s}
  • remove a signal s from a set via sigdelset , S=S\\{s} 通过sigdelset从集合中删除信号s,S = S \\ {s}
  • create the set of all possible signals via sigfillset . 通过sigfillset创建所有可能信号的sigfillset
  • test is a signal s is in a given set S via sigismember , s∈S? test是通过sigismember在给定集合S中的sigismember ,s∈S?

Such a set is used at different places: setting a new process signal mask, blocking set during signal handling, requesting the set of pending signals, etc. 这样的一组用于不同的地方:设置新的过程信号掩码,在信号处理期间阻塞设置,请求待定信号集等。

If you want to catch different signals, it may appears that some catching functions must not be interrupted with others, so you can add a set of signals to be blocked during the delivery of a given signal. 如果您想捕获不同的信号,可能看起来某些捕获功能不能被其他信号中断,因此您可以在传送给定信号期间添加一组要阻止的信号。 You actually decided (when uncommented) to block SIGINT during SIGALRM delivery. 实际上,您决定(在取消注释时)在SIGALRM传递期间阻止SIGINT。 So you can only observe this by sending a SIGINT during the execution of the handler; 所以你只能通过在执行处理程序期间发送SIGINT来观察这个; which is difficult to realize. 这很难实现。

A example where it can be important ? 一个重要的例子吗?

Suppose that the handler of SIGUSR1 modify a given data structure and that the handler for SIGUSR2 uses that same data structure. 假设SIGUSR1的处理程序修改给定的数据结构,并且SIGUSR2的处理程序使用相同的数据结构。 It is very important to make both handlers not concurrent, one can be run after the other but you probably don't want to be interrupted by one during the delivery of the other. 让两个处理程序不并发是非常重要的,一个可以在另一个之后运行,但是你可能不希望在另一个交付期间被一个中断。 Your code is self-concurrent , say that even in the case of only one thread, signals can lead you to concurrency. 您的代码是自并发的 ,即使只有一个线程,信号也可以引导您并发。

sigaddset is used for adding the corresponding signal mask to that sigset_t variable. sigaddset用于将相应的信号掩码添加到该sigset_t变量。

In sigaction, it is not required. 在sigaction中,它不是必需的。 You can use that when you are using the sigprocmask which is for blocking the signal which we mentioning in that variable. 当您使用sigprocmask来阻止我们在该变量中提到的信号时,您可以使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM