信号阻塞与屏蔽:SIG_BLOCK, SIG_UNBLOCK, SIG_MASK区别与使用
1. sigprocmask函数提供屏蔽和解除屏蔽信号的功能。
从而实现关键代码的运行不被打断。
函数声明如下:
#include
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
其中参数 how可设置的参数为:SIG_BLOCK, SIG_UNBLOCK,SIG_SETMASK
SIG_BLOCK:
按照参数 set 提供的屏蔽字,屏蔽信号。并将原信号屏蔽保存到oldset中。
SIG_UNBLOCK:
按照参数 set 提供的屏蔽字进行信号的解除屏蔽。针对Set中的信号进行解屏。
SIG_SETMASK:
按照参数 set 提供的信号设置重新设置系统信号设置。
2. 信号屏蔽与解屏常见实现
方法一: SIG_BLOCK, SIG_UNBLOCK成对实现
优点oldset可以不管。
方法二:
SIG_BLOCK设置屏蔽,保存原有信号设置。
SIG_SETMASK重新恢复原有设置。
3. 屏蔽过程中接受到的信号如何处理
在信号屏蔽过程中,出现的所有被屏蔽的信号,不管发生多少次,
在信号解除屏蔽后,系统会执行一次被屏蔽信号上的操作。
4. 测试代码与结果对比
#include
#include
#include
#include
static void sig_usr1(int signo)
{
printf("SIGUSR1 function\n");
}
static void sig_usr2(int signo)
{
printf("SIGUSR2 function\n");
}
static void sig_int(int signo)
{
printf("SIGINT function\n");
}
void sig_catch(int sig_no, void (*f)(int))
{
struct sigaction sa;
sa.sa_handler = f;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sigaction(sig_no, &sa, (struct sigaction *) 0);
}
main()
{
sigset_t newmask,oldmask;
sig_catch(SIGUSR1,sig_usr1);
sig_catch(SIGUSR2,sig_usr2);
sig_catch(SIGINT,sig_int);
// signal(SIGUSR1,sig_usr1);
// signal(SIGUSR2,sig_usr2);
// signal(SIGINT,sig_int);
sigemptyset(&newmask);
sigaddset(&newmask,SIGUSR1);
sigaddset(&newmask,SIGUSR2);
sigaddset(&newmask,SIGINT);
sigprocmask(SIG_BLOCK,&newmask,&oldmask);
printf("SIGUSR is blocked\n");
kill(getpid(),SIGUSR2);
kill(getpid(),SIGUSR1);
kill(getpid(),SIGUSR2);
kill(getpid(),SIGUSR1);
kill(getpid(),SIGUSR2);
kill(getpid(),SIGUSR1);
kill(getpid(),SIGINT);
printf("SIGUSR is unblocked\n");
//方法一
sigprocmask(SIG_UNBLOCK,&newmask,NULL);
//方法二
sigprocmask(SIG_SETMASK,&oldmask,NULL);
}
结果是相同的:
SIGUSR is blocked
SIGUSR is unblocked
SIGUSR2 function
SIGUSR1 function
SIGINT function
阅读(10068) | 评论(0) | 转发(1) |