1. 程式人生 > >13.訊號捕捉函式:signal;sigaction

13.訊號捕捉函式:signal;sigaction

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訊號處理