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参数返回。