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 *set,int signo); 從set集合中移除signo信號
int sigismember(const sigset_t *set,int signo); signo判斷信號是否存在於set集合中
代碼舉例:
- #include<stdio.h>
- #include<stdlib.h>
- #include<sys/types.h>
- #include<sys/stat.h>
- #include<signal.h>
- int main()
- {
- sigset_t sigset;
- sigfillset(&sigset);/*填充所有信號*/
- if(sigismember(&sigset,SIGINT))/*判斷SIGINT*/
- printf("SIGINT exist in signal_set!\n");
- if(sigismember(&sigset,SIGTERM))
- printf("SIGTERM exist in signal_set!\n");
- if(sigismember(&sigset,SIGABRT))
- printf("SIGABRT exist in signal_set!\n");
- if(sigdelset(&sigset,SIGINT)<0)/*移除SIGINT*/
- perror("del error\n");
- else
- printf("SIGINT have been removed!\n");
- if(sigismember(&sigset,SIGINT))/*再次判斷*/
- printf("SIGINT exist in signal_set!\n");
- else
- 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是一個非空指針時,存放當前屏蔽信號集
若set爲NULL,不改變該進程的信號屏蔽字,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指向的值
舉例
- #include<stdio.h>
- #include<stdlib.h>
- #include<sys/types.h>
- #include<sys/stat.h>
- #include<signal.h>
- /*sigprocmsk的使用*/
- void msg(int signo)
- {
- if(signo==SIGINT)
- printf("Get SIGINT!\n");
- else
- printf("Get SIGQUIT!\n");
- }
- int main()
- {
- sigset_t sigset,oset;/*sigset存放屏蔽信號,oset保存當前屏蔽信號*/
- sigemptyset(&sigset);/*清空信號集*/
- sigaddset(&sigset,SIGINT);/*添加SIGINT信號,信號集中僅有SIGINT*/
- sigprocmask(SIG_BLOCK,&sigset,&oset);/*加入屏蔽信號*/
- signal(SIGINT,msg);
- signal(SIGQUIT,msg);
- sleep(2);
- raise(SIGINT);/*發送SIGINT信號*/
- 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; /*標誌位,對信號進程處理選項*/
} ;
舉例
- #include<stdio.h>
- #include<stdlib.h>
- #include<sys/types.h>
- #include<sys/stat.h>
- #include<signal.h>
- void msg(int signo)
- {
- if(signo==SIGINT)
- printf("Get SIGINT!\n");
- }
- int main()
- {
- sigset_t sigset,oset;/*sigset存放屏蔽信號,oset保存當前屏蔽信號*/
- struct sigaction action1,action2;/*信號處理*/
- action1.sa_handler=msg;
- sigaction(SIGINT,&action1,&action2);
- sleep(2);
- raise(SIGINT);/*發送SIGINT信號*/
- }
輸出:
Get SIGINT
<4>檢測被擱置信號
Int sigpending(sigset_t *set);
返回對於調用進程被阻塞不能遞送和當前未決的信號集。該信號集通過s e t參數返回。