signal和sigaction

    技术2022-11-25  11

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

    最新回复(0)