sigprocmask( ) 在 UNIX 中阻塞信号

发布于 2024-10-21 17:03:54 字数 1598 浏览 3 评论 0原文

我写了一小段代码。此代码首先阻止 {SIGSEGV},然后将 SIGRTMIN 添加到同一组。所以,我的最终信号集是 {SIGSEGV,SIGRTMIN}。因此,如果我使用 SIG_UNBLOCK,根据我的理解,首先 SIGRTMIN 应该被解锁,然后如果我调用 SIG_UNBLOCK,SIGSEGV 应该被解锁。

也就是说,1) {SIGSEGV,SIGRTMIN} 2) SIG_UNBLOCK = 解锁 SIGRTMIN,3) 再次调用 SIG_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)

i have written a small piece of code. This code first blocks the {SIGSEGV}, then adds SIGRTMIN to the same set. So, my final signal set is, {SIGSEGV,SIGRTMIN}. Thus, if i use SIG_UNBLOCK, as per my understanding, first SIGRTMIN should be unblocked, and then again if i invoke SIG_UNBLOCK, SIGSEGV should be unblocked.

That is, 1) {SIGSEGV,SIGRTMIN} 2) SIG_UNBLOCK = unblock SIGRTMIN, 3) Again invoke SIG_UNBLOCK = unblock SIGSEGV.
I am giving the process a SIGRTMIN only, thus my second unblock should halt the process with SIGRTMIN. But it is not. Please help.
N.B: Please don't give links to answers of other questions on sigprocmask( ), i have seen them and they don't clarify my question.

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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

萌辣 2024-10-28 17:03:54

你的前提是错误的。通过一次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 函数。

Your premise is wrong. The whole set gets blocked and unblocked with a single call of sigprocmask.

Also, normally you would create a set containing every signal you want to block, then you would attempt to block them all with sigprocmask(SIG_BLOCK, pointer_to_sigset);.

Your code doesn't really unblock SIGSEGV though. Here's what i would write WITHOUT error handling, because it would make the snippet unnecessarily long. Check every function
for errors though, the lists of possible errors are provided by man pages:

/* ... */
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 */

Of course, you might want to split blocking the signals into two operations on separate sets. The mechanism works like this: there is some set of blocked signals, which would replace oldset if you provided an oldset argument. You can add to that set with SIG_BLOCK, remove from that set with SIG_UNBLOCK, and change the whole set to your liking with SIG_SETMASK arguments of the sigprocmask function.

送舟行 2024-10-28 17:03:54

正如 kubi 指出的:这是修改后的代码,问题是,我搞乱了 old_set 和 new_set。 SIGSEGV被添加到old_set中,它没有被解锁,因此我没有收到分段错误(SIGSEGV信号)。
感谢库比。

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,&new_set,&old_set); // SIGSEGV signal is masked
 kill(0,SIGSEGV);


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

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


//****************** Unblock all signals  ******************

if(sigprocmask(SIG_UNBLOCK,&new_set,&old_set)==-1) // SIGRTMIN signal is unmasked
 {
  perror("sigprocmask");
 }
}

As kubi pointed out: Here is the modified code, problem is that, i messed up with old_set and new_set. The SIGSEGV was added in old_set, which was not unblocked, and hence i did not receive Segmentation fault (SIGSEGV signal).
Thanks to kubi.

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,&new_set,&old_set); // SIGSEGV signal is masked
 kill(0,SIGSEGV);


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

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


//****************** Unblock all signals  ******************

if(sigprocmask(SIG_UNBLOCK,&new_set,&old_set)==-1) // SIGRTMIN signal is unmasked
 {
  perror("sigprocmask");
 }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文