Linux 信號集

Linux信號集

1.    信號集概念

信號集是一個能表示多個信號的數據類型,sigset_t set set即一個信號集。

既然是一個集合,就需要對集合進行添加/刪除等操作。

int sigemptyset(sigset_t *set); set集合置空

int sigfillset(sigset_t *set) 將所有信號加入set集合

int sigaddset(sigset_t *set,int signo); signo信號加入到set集合

int sigdelset(sigset_t *setint signo); set集合中移除signo信號

int sigismember(const sigset_t *set,int signo); signo判斷信號是否存在於set集合中

代碼舉例:

 

  1. #include<stdio.h> 
  2. #include<stdlib.h> 
  3. #include<sys/types.h> 
  4. #include<sys/stat.h> 
  5. #include<signal.h> 
  6.  
  7.  
  8. int main() 
  9.     sigset_t sigset; 
  10.      
  11.     sigfillset(&sigset);/*填充所有信號*/ 
  12.      
  13.     if(sigismember(&sigset,SIGINT))/*判斷SIGINT*/ 
  14.         printf("SIGINT exist in signal_set!\n"); 
  15.     if(sigismember(&sigset,SIGTERM)) 
  16.         printf("SIGTERM exist in signal_set!\n");    
  17.     if(sigismember(&sigset,SIGABRT)) 
  18.         printf("SIGABRT exist in signal_set!\n"); 
  19.      if(sigdelset(&sigset,SIGINT)<0)/*移除SIGINT*/ 
  20.         perror("del error\n"); 
  21.         else 
  22.             printf("SIGINT have been removed!\n"); 
  23.      if(sigismember(&sigset,SIGINT))/*再次判斷*/ 
  24.         printf("SIGINT exist in signal_set!\n"); 
  25.         else 
  26.             printf("SIGINT not exist in signal_set!\n"); 

輸出:

$ ./sigset

SIGINT exist in signal_set!

SIGTERM exist in signal_set!

SIGABRT exist in signal_set!

SIGINT have been removed!

SIGINT not exist in signal_set!

 

2.    信號集的使用

定義信號集->設置信號屏蔽位->定義信號處理函數->檢測信號

 

<1>使用1中的函數即可完成信號集的定義,之後是

 

<2>設置信號屏蔽位

其作用爲設置某個進程需要屏蔽的信號

Int sigprocmask(int how,const sigset_t *set,sigset_t *oset);

參數

How 指示如何修改屏蔽信號

Set是一個非空指針時,根據how修改屏蔽信號

Oset是一個非空指針時,存放當前屏蔽信號集

setNULL,不改變該進程的信號屏蔽字,how也無意義

 

How的取值:

S I G B L O C K

該進程新的信號屏蔽字是其當前信號屏蔽字和s e t指向信號集的並集。s e t包含了我們希望阻塞的附加信號

S I G U N B L O C K

該進程新的信號屏蔽字是其當前信號屏蔽字和s e t所指向信號集的交集。s e t包含了我們希望解除阻塞的信號

S I G S E T M A S K

該進程新的信號屏蔽是s e t指向的值

 

舉例

 

  1. #include<stdio.h> 
  2. #include<stdlib.h> 
  3. #include<sys/types.h> 
  4. #include<sys/stat.h> 
  5. #include<signal.h> 
  6.  
  7. /*sigprocmsk的使用*/ 
  8. void msg(int signo) 
  9.     if(signo==SIGINT) 
  10.         printf("Get SIGINT!\n"); 
  11.     else 
  12.         printf("Get SIGQUIT!\n"); 
  13. int main() 
  14.     sigset_t sigset,oset;/*sigset存放屏蔽信號,oset保存當前屏蔽信號*/ 
  15.      
  16.     sigemptyset(&sigset);/*清空信號集*/ 
  17.     sigaddset(&sigset,SIGINT);/*添加SIGINT信號,信號集中僅有SIGINT*/ 
  18.      
  19.      
  20.     sigprocmask(SIG_BLOCK,&sigset,&oset);/*加入屏蔽信號*/ 
  21.      
  22.     signal(SIGINT,msg); 
  23.     signal(SIGQUIT,msg); 
  24.     sleep(2); 
  25.     raise(SIGINT);/*發送SIGINT信號*/ 
  26.     raise(SIGQUIT); 

輸出

Get SIGQUIT!

 

<3>定義信號處理函數

s i g a c t i o n函數的功能是檢查或修改(或兩者)與指定信號相關聯的處理動作。此函數取代了U N I X早期版本使用的s i g n a l函數

 

Int sigaction(int signo,const struct sigaction *act,struct sigaction *oact);

參數:signo 要檢測或修改動作的信號量

      Act 非空時,表示要修改的動作

      Oact非空時,返回處理該信號的原先動作

結構體sigaction如下:

struct sigaction {

void (*sa_handler)();/*處理函數或SIG_IGN(忽略)SIG_DFL(默認)*/

sigset_t sa_mask; /*處理函數過程中被阻塞*/

int sa_flags; /*標誌位,對信號進程處理選項*/

} ;

舉例

 

  1. #include<stdio.h> 
  2. #include<stdlib.h> 
  3. #include<sys/types.h> 
  4. #include<sys/stat.h> 
  5. #include<signal.h> 
  6.  
  7. void msg(int signo) 
  8.     if(signo==SIGINT) 
  9.     printf("Get SIGINT!\n"); 
  10. int main() 
  11.     sigset_t sigset,oset;/*sigset存放屏蔽信號,oset保存當前屏蔽信號*/ 
  12.     struct sigaction action1,action2;/*信號處理*/ 
  13.     action1.sa_handler=msg; 
  14.     sigaction(SIGINT,&action1,&action2); 
  15.     sleep(2); 
  16.     raise(SIGINT);/*發送SIGINT信號*/ 

輸出:

Get SIGINT

 

<4>檢測被擱置信號

Int sigpending(sigset_t *set);

返回對於調用進程被阻塞不能遞送和當前未決的信號集。該信號集通過s e t參數返回。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章