UNIX sigaction函數詳解

sigaction函數的功能是檢查或修改與指定信號相關聯的處理動做(可同時兩種操做)。是POSIX的信號接口,而signal()是標準C的信號接口(若是程序必須在非POSIX系統上運行,那麼就應該使用這個接口)函數

給信號signum設置新的信號處理函數act, 同時保留該信號原有的信號處理函數oldactspa

 

int sigaction(int signo,const struct sigaction *restrict act,指針

 

              struct sigaction *restrict oact);rest

 

結構sigaction定義以下:接口

struct sigaction{進程

   void (*sa_handler)(int);io

    sigset_t sa_mask;軟件

   int sa_flag;程序

   void (*sa_sigaction)(int,siginfo_t *,void *);margin

};

注:

sa_handler字段包含一個信號捕捉函數的地址

sa_mask字段說明了一個信號集,在調用該信號捕捉函數以前,這一信號集要加進進程的信號屏蔽字中。僅當從信號捕捉函數返回時再將進程的信號屏蔽字復位爲原先值。

sa_flag是一個選項,主要理解兩個

SA_INTERRUPT 由此信號中斷的系統調用不會自動重啓

SA_RESTART 由此信號中斷的系統調用會自動重啓

SA_SIGINFO 提供附加信息,一個指向siginfo結構的指針以及一個指向進程上下文標識符的指針

 

最後一個參數是一個替代的信號處理程序,當設置SA_SIGINFO時纔會用他。

例子:

 

 #include <stdio.h>

 #include <signal.h>

 #include <unistd.h>

 

 void show_handler(int sig)

 {

     printf("I got signal %d\n", sig);

     int i;

     for(i = 0; i < 5; i++) {

         printf("i = %d\n", i);

         sleep(1);

     }

 }

 

 int main(void)

 {

     int i = 0;

     struct sigaction act, oldact;

     act.sa_handler = show_handler;

     sigaddset(&act.sa_mask, SIGQUIT); //見注(1)

     act.sa_flags = SA_RESETHAND | SA_NODEFER; //見注(2)

    //act.sa_flags = 0; //見注(3)

 

     sigaction(SIGINT, &act, &oldact);

     while(1) {

         sleep(1);

         printf("sleeping %d\n", i);

         i++;

     }

 }

注:

(1)    若是在信號SIGINT(Ctrl + c)的信號處理函數show_handler執行過程當中,本進程收到信號SIGQUIT(Crt+\),將阻塞該信號,直到show_handler執行結束纔會處理信號SIGQUIT。

(2)    SA_NODEFER       通常狀況下, 當信號處理函數運行時,內核將阻塞<該給定信號 -- SIGINT>。可是若是設置了SA_NODEFER標記, 那麼在該信號處理函數運行時,內核將不會阻塞該信號。 SA_NODEFER是這個標記的正式的POSIX名字(還有一個名字SA_NOMASK,爲了軟件的可移植性,通常不用這個名字)    

        SA_RESETHAND    當調用信號處理函數時,將信號的處理函數重置爲缺省值。 SA_RESETHAND是這個標記的正式的POSIX名字(還有一個名字SA_ONESHOT,爲了軟件的可移植性,通常不用這個名字)   

 (3)    若是不須要重置該給定信號的處理函數爲缺省值;而且不須要阻塞該給定信號(無須設置sa_flags標誌),那麼必須將sa_flags清零,不然運行將會產生段錯誤。可是sa_flags清零後可能會形成信號丟失!

相關文章
相關標籤/搜索