sigaction
#include <signal.h>
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; int sa_flags; void (*sa_restorer)(void); };
通過sa_mask設置信號掩碼集。
信號處理函數可以采用void (*sa_handler)(int)或void (*sa_sigaction)(int, siginfo_t *, void *)。到底采用哪個要看sa_flags中是否設置了SA_SIGINFO位,如果設置了就采用void (*sa_sigaction)(int, siginfo_t *, void *),此時可以向處理函數發送附加信息;默認情況下采用void (*sa_handler)(int),此時只能向處理函數發送信號的數值。
sa_falgs還可以設置其他標志:
SA_RESETHAND:當調用信號處理函數時,將信號的處理函數重置為缺省值SIG_DFL
SA_RESTART:如果信號中斷了進程的某個系統調用,則系統自動啟動該系統調用
SA_NODEFER :一般情況下, 當信號處理函數運行時,內核將阻塞該給定信號。但是如果設置了SA_NODEFER標記, 那么在該信號處理函數運行時,內核將不會阻塞該信號
#include<stdio.h> #include<signal.h> #include<stdlib.h> #include<string.h> #define INPUTLEN 100 void inthandler(int); int main(){ struct sigaction newhandler; sigset_t blocked; //被阻塞的信號集 char x[INPUTLEN]; newhandler.sa_flags=SA_RESETHAND; newhandler.sa_handler=inthandler; sigemptyset(&blocked); //清空信號處理掩碼 sigaddset(&blocked,SIGQUIT); newhandler.sa_mask=blocked; if(sigaction(SIGINT,&newhandler,NULL)==-1) perror("sigaction"); else while(1){ fgets(x,INPUTLEN,stdin); //fgets()會在數據的最后附加"\0" printf("input:%s",x); } } void inthandler(int signum){ printf("Called with signal %d\n",signum); sleep(signum); printf("done handling signal %d\n",signum); }復制代碼
Ctrl-C向進程發送SIGINT信號,Ctrl-\向進程發送SIGQUIT信號。
$ ./sigactdemo ^CCalled with signal 2 ^\done handling signal 2 Quit (core dumped)
由于把SIGQUIT加入了信號掩碼集,所以處理信號SIGINT時把SIGQUIT屏蔽了。當處理完SIGINT后,內核才向進程發送SIGQUIT信號。
$ ./sigactdemo ^CCalled with signal 2 ^Cdone handling signal 2
由于設置了SA_RESETHAND,第一次執行SIGINT的處理函數時相當于執行了signal(SIGINT,SIG_DFL),所以進程第二次收到SIGINT信號后就執行默認操作,即掛起進程。
修改代碼,同時設置SA_RESETHAND和SA_NODEFER。
newhandler.sa_flags=SA_RESETHAND|SA_NODEFER;
$ ./sigactdemo ^CCalled with signal 2 ^C
在沒有設置SA_NODEFER時,在處理SIGINT信號時,自動屏幕SIGINT信號。現在設置了SA_NODEFER,則當SIGINT第二次到來時立即響應,即掛起了進程。
http://www.cnblogs.com/zhangchaoyang/articles/2297536.html
轉載于:https://www.cnblogs.com/newlist/archive/2012/02/09/2343508.html
總結
 
                            
                        