我写了一小段代码。此代码首先阻塞 {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 停止进程。但事实并非如此。请帮忙。
N.B:请不要在 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 - sigprocmask() 在 UNIX 中阻塞信号,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5288910/