sigprocmask()在UNIX中阻塞信号

kin*_*er1 6 c unix signals sigprocmask

我写了一小段代码.此代码首先阻塞{SIGSEGV},然后将SIGRTMIN添加到同一个集合中.所以,我的最终信号集是{SIGSEGV,SIGRTMIN}.因此,如果我使用SIG_UNBLOCK,根据我的理解,第一个SIGRTMIN应该被解除阻塞,然后如果我调用SIG_UNBLOCK,则应该取消阻塞SIGSEGV.

即,1){SIGSEGV,SIGRTMIN} 2)SIG_UNBLOCK = unblock SIGRTMIN,3)再次调用SIG_UNBLOCK = unblock SIGSEGV.我只给了进程一个SIGRTMIN,因此我的第二个unblock应该用SIGRTMIN暂停进程.但事实并非如此.请帮忙. 注意:请不要给sigprocmask()上的其他问题的答案链接,我已经看过他们,他们没有澄清我的问题.

enter code here
#include <signal.h>
#include <unistd.h>
#include <stdio.h>

int main()
{
 sigset_t old_set,new_set;
 sigemptyset(&old_set);
 sigemptyset(&new_set);

 if(sigaddset(&old_set,SIGSEGV)==0)
 {
   printf("sigaddset successfully added for SIGSEGV\n");
 }
 sigprocmask(SIG_BLOCK,&old_set,NULL); // SIGSEGV signal is masked
 kill(0,SIGSEGV);


 //*****************************************************************

 if(sigaddset(&new_set,SIGRTMIN)==0)
 {
  printf("sigaddset successfully added for SIGRTMIN\n");
 }
  sigprocmask(SIG_BLOCK,&new_set,&old_set); // SIGRTMIN signal is masked
 kill(0,SIGSEGV);

 //****************** Unblock one signal at a time ******************

 sigprocmask(SIG_UNBLOCK,&new_set,&old_set); // SIGRTMIN signal is unmasked
 sigprocmask(SIG_UNBLOCK,&new_set,&old_set); // SIGSEGV signal is unmasked
Run Code Online (Sandbox Code Playgroud)

}

Output:
 [root@dhcppc0 signals]# ./a.out
  sigaddset successfully added for SIGSEGV
  sigaddset successfully added for SIGRTMIN
  (Note:SIGSEGV is not received even after sigprocmask(SIG_UNBLOCK,&new_set,&old_set); a second time)
Run Code Online (Sandbox Code Playgroud)

kub*_*ubi 12

你的前提是错的.只需一次调用,整个集就会被阻止和解锁sigprocmask.

此外,通常你会创建一个包含你想要阻止的每个信号的集合,然后你会尝试用它们阻止它们sigprocmask(SIG_BLOCK, pointer_to_sigset);.

您的代码并没有真正解锁SIGSEGV.这是我写的没有错误处理,因为它会使代码段不必要地长.检查每个函数是否有错误,可能的错误列表由手册页提供:

/* ... */
sigset_t signal_set; /* We don't need oldset in this program. You can add it,
                        but it's best to use different sigsets for the second
                        and third argument of sigprocmask. */
sigemptyset(&signal_set);

sigaddset(&signal_set, SIGSEGV);
sigaddset(&signal_set, SIGRTMIN);

/* now signal_set == {SIGSEGV, SIGRTMIN} */

sigprocmask(SIG_BLOCK, &signal_set, NULL): /* As i said, we don't bother with the 
                                              oldset argument. */

kill(0,SIGSEGV);  
kill(0,SIGSEGV);  /* SIGSEGV is not a realtime signal, so we can send it twice, but
                     it will be recieved just once */

sigprocmask(SIG_UNBLOCK, &signal_set, NULL); /* Again, don't bother with oldset */

/* SIGSEGV will be received here */
Run Code Online (Sandbox Code Playgroud)

当然,您可能希望将信号分开阻塞在不同的集合上的两个操作中.该机制的工作原理如下:有一些阻塞信号,如果你提供了一个oldset参数,它将取代oldset.您可以添加到该集合SIG_BLOCK,从该集合中删除SIG_UNBLOCK,并使用SIG_SETMASKsigprocmask函数的参数将整个集合更改为您喜欢的集合.