c - UNIX 中的 sigprocmask( ) 阻塞信号

标签 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,因此我的第二个解锁应该用 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

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)

最佳答案

你的前提是错误的。只需调用一次 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 */

当然,您可能希望将阻塞信号拆分为两个单独集合上的操作。该机制是这样工作的:有一些阻塞信号集,如果您提供了 oldset 参数,它将替换 oldset。您可以使用 SIG_BLOCK 添加到该集合,使用 SIG_UNBLOCK 从该集合中删除,并使用 SIG_SETMASK 参数更改整个集合sigprocmask 函数。

关于c - UNIX 中的 sigprocmask( ) 阻塞信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5288910/

相关文章:

c - 如何在 C 应用程序中处理冲突的结构定义

c - 在 C 编程中的链表末尾追加一个元素

c - 如何在我的结构中使用类型定义的枚举?

linux - 创建.so文件

linux - x 服务器和应用程序客户端

c - 与 gcc 相比,为什么 clang 对寄存器变量的行为很奇怪?

linux - 将给定类型的所有文件从 Unix 格式转换为 Dos 格式的 Bash 脚本

c++ - 在 sigpipe 之后恢复 stdout 和 stderr

linux - 如何在 systemd 控制组之外启动进程

linux - Linux 信号在内核内部的什么地方发送或处理?