信号设置SIG_BLOCK
当内核发送的信号来时,不会发送到进程。但是当阻塞被清除时,阻塞的信号还是会发送到进程中。
未决信号可以如下方式检测
//获取当前的阻塞未决信号
if(sigpending(&pendset) < 0)
{
perror("sigpending error!");
exit(1);
}else
{
//查询当前的未决信号中是否有SIGINT中
if(sigismember(&pendset, SIGINT))
{
//todo
}else
{
//to do
}
}
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
void handle_signale_func(int sig);
void handle_signale_alarm(int sig);
int main(int argc, char *argv[])
{
sigset_t set, pendset;
struct sigaction action1, action2;
// signal(SIGALRM, handle_signale_alarm);
//5秒闹钟信号到,给进程发送结束信号
// alarm(5);
//初始化信号集合
if(sigemptyset(&set) < 0)
{
perror("sigemptyset error!");
exit(1);
}
//信号加入到集合中
if(sigaddset(&set, SIGQUIT) < 0)
{
perror("sigaddset error!");
exit(1);
}
if(sigaddset(&set, SIGINT) < 0)
{
perror("sigaddset SIGINT error!");
exit(1);
}
//检查信号是否在集合当中
if(sigismember(&set, SIGINT))
{
sigemptyset(&action1.sa_mask);
action1.sa_handler = handle_signale_func;
action1.sa_flags = 0;
sigaction(SIGINT, &action1, NULL);
}
if(sigismember(&set, SIGQUIT))
{
sigemptyset(&action2.sa_mask);
action2.sa_handler = SIG_DFL;
action2.sa_flags = 0;
sigaction(SIGQUIT, &action2, NULL);
}
//设置信号屏蔽字
if(sigprocmask(SIG_BLOCK, &set, NULL) < 0)
{
perror("sigprocmask error!");
exit(1);
}else
{
printf("signal set blocked , Press any key!\n");
getchar();
}
//删除一个信号集
if(sigprocmask(SIG_UNBLOCK, &set, NULL) < 0)
{
perror("sigprocmask SIG_UNBLOCK error!");
exit(1);
}else
{
printf("signal set unblock state!\n");
}
#if 0
//获取当前的阻塞未决信号
if(sigpending(&pendset) < 0)
{
perror("sigpending error!");
exit(1);
}else
{
//查询当前的未决信号中是否有SIGINT中
if(sigismember(&pendset, SIGINT))
{
printf("cur pending signal is SIGINT \n");
}else
{
printf("the process exist peend sig, but, dont SIGINT!\n");
}
}
//删除一个信号集
if(sigprocmask(SIG_UNBLOCK, &set, NULL) < 0)
{
perror("sigprocmask SIG_UNBLOCK error!");
exit(1);
}else
{
printf("signal set unblock state!\n");
}
while(1)
{
//获取当前的阻塞未决信号
if(sigpending(&pendset) < 0)
{
perror("sigpending error!");
exit(1);
}else
{
//查询当前的未决信号中是否有SIGINT中
if(sigismember(&pendset, SIGINT))
{
printf("cur pending signal is SIGINT \n");
}else
{
printf("the process exist peend sig, but, dont SIGINT!\n");
}
}
sleep(1);
}
#endif
while(1);
exit(0);
}
void handle_signale_func(int sig)
{
printf("你杀不死我!\n");
}
void handle_signale_alarm(int sig)
{
printf("handle_signale_alarm pid:%d\n", getpid());
kill(getpid(), SIGHUP);
}
总结:
1、信号处理的繁重方式:忽略(SIG_IGN)、默认(SIG_DFL)、注册回调自行处理(signal)
2、kill发送信号到指定进程,raise可以发送信号给自己
3、被屏蔽的信号并不会被丢弃,只是被暂时保存起来了。等到解除屏蔽之后,还是会发送到进程中