本文主要是介绍signal和sigaction,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
signal用于系统信号回调处理,有一下几个要注意的问题。
1)系统调用的中断重入。
2)不可靠性。
3)某些函数的不可重入性,如malloc,或者使用全局静态变量等返回结果等。
下面是用老的signal的信号处理方式:
int main(int argc,char** args){
char cs[LINE_LEN];
signal(SIGINT,handleInfoSingal);
read(STDIN_FILENO,cs,100);
sigset_t st,oldst,pendingst;
sigemptyset(&st);
sigaddset(&st,SIGINT);
sigprocmask(SIG_BLOCK,&st,&oldst);
printfln("begin sleep!");
sleep(5);
printfln("wark up!");
sigpending(&pendingst);
if(sigismember(&pendingst,SIGINT)){
printfln("have it in sleep!");
}else{
printfln("not have it in sleep");
}
printfln("begin to recover!");
sigprocmask(SIG_SETMASK,&oldst,NULL);
printfln("end to recover!");
int i=0;
exit(0);
}
当系统阻塞在读取控制台的系统调用的时候,按下ctrl+c的时候,系统回打印出当前的pid,而后回重新等待用户输入。
但是你联系在此过程中按下多次ctrl+c,不会理会,这个时候因为
采用了sigaction重写以后,必须要在sa_flags加入SA_REATRT或者SA_INTERCEPT,才能够对重新启动系统调用。
typedef void (*handleSignal)(int singal);
void handleInfoSingal(int singal){
printfln("%i-",getpid());
sleep(1);
printfln("%i+",getpid());
}
handleSignal signal1(int signalNo,handleSignal hs){
printfln("custom signal!");
struct sigaction sa,oa;
sa.sa_handler=hs;
sigemptyset(&sa.sa_mask);
sa.sa_flags=0;
#IFDEF SA_INTERRUPT
sa.sa_flags|=SA_RESTART;
#ENDIF
#IFDEF SA_RESTART
sa.sa_flags|=SA_RESTART;
#ENDIF
sigaction(signalNo,&sa,&oa);
return oa.sa_handler;
}
int main(int argc,char** args){
char cs[LINE_LEN];
signal1(SIGINT,handleInfoSingal);
read(STDIN_FILENO,cs,100);
sigset_t st,oldst,pendingst;
sigemptyset(&st);
sigaddset(&st,SIGINT);
sigprocmask(SIG_BLOCK,&st,&oldst);
printfln("begin sleep!");
sleep(5);
printfln("wark up!");
sigpending(&pendingst);
if(sigismember(&pendingst,SIGINT)){
printfln("have it in sleep!");
}else{
printfln("not have it in sleep");
}
printfln("begin to recover!");
sigprocmask(SIG_SETMASK,&oldst,NULL);
printfln("end to recover!");
int i=0;
exit(0);
}
除此,SIGALARM信号不需要这种处理方式。
这篇关于signal和sigaction的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!