1.signal函数
sighandler_t signal(int signum, sighandler_t handler);
__sighandler_t signal(int signo,sighandler handler)
返回值:返回前一次设置的handler
参数:
handler
SIG_IGN 屏蔽
SIG_DFL 恢复默认行为
案例:返回前一次的handler
void handler(int arg){
printf("++++++++++++++\n");
}
int main(){
__sighandler_t oldhandler=signal(SIGINT,handler);
if(oldhandler==SIG_ERR)
perror("signal error");
while(1){
if(getchar()=='q')
signal(SIGINT,oldhandler); //signal(SIGINT,SIG_DFL);
}
return 0;
}
2.sigcation函数
int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
struct sigaction {
void (*sa_handler)(int); //信号处理函数指针
void (*sa_sigaction)(int, siginfo_t *, void *); //一般不用
sigset_t sa_mask;
//在信号处理函数执行过程中,[临时][屏蔽]指定的信号
//当sa_handler信号处理函数执行完成后,才执行[临时][屏蔽]的信号的处理函数
int sa_flags; //0 - sa_handler
void (*sa_restorer)(void); //不用管
};
参数赋值(3个):
void (*sa_handler)(int); //信号处理函数指针
int sa_flags;
sigset_t sa_mask;
sigemptyset(&act.sa_mask); // 清空sa_mask
//sigaddset(&act.sa_mask,SIGQUIT); // 向sa_mask中添加[待屏蔽][临时]信号
总结:signal/sigaction的区别
signal/sigaction相同点:
都注册信号和信号处理回调函数
signal/sigaction不同点:
sigaction:注册[临时][屏蔽]信号
综合案例
void handler(){
printf("handler: Ctrl+C \n");
sleep(3);
printf("handler: wake up \n");
}
int main(){
struct sigaction act;
//初始化act
act.sa_flags=0;
sigemptyset(&act.sa_mask); //清空sa_mask
//sigaddset(&act.sa_mask,SIGQUIT); //注释?不注释?
act.sa_handler=handler;
sigaction(SIGINT,&act,NULL);
while(1){
sleep(1);
}
}
程序执行分析:
sigaddset(&act.sa_mask,SIGQUIT);
1.注释
连续按ctrl+C多次,接着按ctrl+\,程序立即被ctrl+\产生的SIGQUIT信号终止
2.不注释
连续按ctrl+C多次,接着按ctrl+\,程序[不会]立即被ctrl+\产生的SIGQUIT信号终止
而是等待handler信号处理函数执行完毕后,再被SIGQUIT信号终止
1和2的区别是:
是否等待handler信号处理函数执行完,再进行SIGQUIT信号处理