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信号不需要这种处理方式。