13.訊號捕捉函式:signal;sigaction
阿新 • • 發佈:2018-11-12
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訊號處理