可靠机制,不会恢复默认信号处理程序:
新的信号安装函数sigaction:sigaction函数用于改变进程收到的特定信号后的行为
int sigaction(int signum,const struct sigaction *act,const struct sigaction *old); //成功返回0,失败返回-1
struct sigaction{
void (*sa_handler)(int);
sigset_t sa_mask;//屏蔽集合
int sa_flags;
//可选
void (*sa_sigaction) (int,siginfo_t*,void*) //与void (*sa_handler)(int)任选其一,这个针对可靠信号
}
1、第一个参数为信号的值,可以为除SIGKILL以及SIGSTOP外的任何一个特定有效的信号;
2、第二个参数是一个指向结构sigaction的一个实例的指针,在结构sigaction的实例中,指定了对特定
信号的处理,可以为空,进程会以缺省的方式对信号处理;这个结构体包含了对指定信号的处理,信号传导的信息,信号处理函数执行过程中应屏蔽掉哪些函数。
3、第三个参数oldact指向的对象用来保存原来对应信号的处理函数,可以指定oldact为NULL
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdlib.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>
#include<signal.h>
#define ERR_EXIT(m)\
do\
{\
perror(m);\
exit(EXIT_FAILURE);\
}while(0) //宏要求一条语句
void handler(int sig);
int main(int argc,char*argv[])
{
struct sigaction act;
act.sa_handler=handler;
sigemptyset(&act.sa_mask);
act.sa_flags=0;
if(sigaction(SIGINT,&act,NULL)<0)
ERR_EXIT("sigaction error\n");
for(;;)
pause();
return 0;
}
void handler(int sig)//sig是signum
{
printf("receive a sig=%d\n",sig);
}
linux中signal建立在可靠机制之上(信号在安装完,执行处理函数后,信号处理函数不会自动恢复到默认),用sigaction来模拟实现signal:
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdlib.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>
#include<signal.h>
#define ERR_EXIT(m)\
do\
{\
perror(m);\
exit(EXIT_FAILURE);\
}while(0) //宏要求一条语句
void handler(int sig);
__sighandler_t my_signal(int sig,__sighandler_t handler);
int main(int argc,char*argv[])
{
struct sigaction act;
act.sa_handler=handler;
sigemptyset(&act.sa_mask);
act.sa_flags=0;
// if(sigaction(SIGINT,&act,NULL)<0)
// ERR_EXIT("sigaction error\n");
my_signal(SIGINT,handler);
for(;;)
pause();
return 0;
}
__sighandler_t my_signal(int sig,__sighandler_t handler)//signal出错返回SIG_ERR
{
struct sigaction act;
struct sigaction oldact;
act.sa_handler=handler;
sigemptyset(&act.sa_mask);
act.sa_flags=0;
if(sigaction(sig,&act,&oldact)<0)
return SIG_ERR;
return oldact.sa_handler;
}
void handler(int sig)//sig是signum
{
printf("receive a sig=%d\n",sig);
}
sigaction 中sa_mask:指定信号屏蔽字(调用信号处理函数所在的线程的信号屏蔽字中),其他信号如果在信号处理程序过程中到来,则它们会在信号处理函数执行时被阻塞。等到信号处理函数运行完,被屏蔽的信号才会递达。不同于sigprocmask,sigprocmask阻塞的信号,根本不会递达, 只会处于未决状态,不会执行信号处理程序。
1 #include<unistd.h>
2 #include<sys/types.h>
3 #include<sys/stat.h>
4 #include<fcntl.h>
5 #include<stdlib.h>
6 #include<stdio.h>
7 #include<errno.h>
8 #include<string.h>
9
10 #include<signal.h>
11 #define ERR_EXIT(m)\
12 do\
13 {\
14 perror(m);\
15 exit(EXIT_FAILURE);\
16 }while(0) //宏要求一条语句
17 void handler(int sig);
18 int main(int argc,char*argv[])
19 {
20 struct sigaction act;
21 act.sa_handler=handler;
22 sigemptyset(&act.sa_mask);
23 act.sa_flags=0;
24
25 sigaddset(&act.sa_mask,SIGQUIT);
26 if(sigaction(SIGINT,&act,NULL)<0)//若不指定sa_mask,若指定的话,SIGQUIT信号在SIGINT处理程序执行期间都被阻塞。
27 ERR_EXIT("sigaction error\n");
28 for(;;)
29 pause();
30 return 0;
31 }
32
33 void handler(int sig)//sig是signum。信号处理函数过程中,屏蔽sa_mask
34 {
35 printf("receive a sig=%d\n",sig);
36 sleep(5);//不设置sa_mask的话,未返回时按ctrl+\直接退出,不能阻塞新的信号。阻塞结束,SIGQUIT信号递达
37 }
来源:https://www.cnblogs.com/wsw-seu/p/8367125.html