12.信号集函数:sigemptyset;sigfillset;sigaddset;sigdelset;sigismember;sigpending

信号处理的工作原理:阻塞信号集/未决信号集

未决信号集:
	没有被当前进程处理的信号集
阻塞信号集:
	将某个信号放到阻塞信号集,这个信号就不会被进程处理
	阻塞解除后,信号被处理
---------------------------------------------------------------
信号处理的工作原理:内核PCB中,存放着未决信号集/阻塞信号集
1.当产生信号XXX时,将在[未决信号集]中将XXX信号的标志位设为1
2.放入[未决信号集]中的XXX信号等待处理,在处理之前需要做一件事:判断
[阻塞信号集]中的XXX信号的标志位是否为1(如果为1,不处理XXX信号;如
果为0,处理XXX信号)

信号集函数

int sigemptyset(sigset_t *set);   //将set集合置空
int sigfillset(sigset_t *set); //将所有信号加入set集合

int sigaddset(sigset_t *set, int signum); //将signum信号加入set集合
int sigdelset(sigset_t *set, int signum); //从set集合中移除signum信号

int sigprocmask(int how, const sigset_t *set, sigset_t *oldset); //将自定义信号集放在内核中的[阻塞信号集]中
参数:
	how取值,假设当前的信号屏蔽字为mask
		SIG_BLOCK:mask=mask|set      添加屏蔽字
		SIG_UNBLOCK:mask=mask|~set    解除屏蔽字
		SIG_SETMASK:mask=set
	set:传出的新的set
	oldset:设置之前的当前的信号屏蔽字集合
	使用:sigprocmask(___,&set,NULL);
	
int sigpending(sigset_t *set); //读取当前进程的未决信号集sigpendset
	
int sigismember(const sigset_t *set, int signum); //判断set集合中是否存在signum信号

案例1:[获取]当前进程的未决信号集

int main(){        
  //每隔1s获取一次内存的未决信号集
  while(1){                                                                                                                      
    sigset_t pendset;                                                                                                            
    sigpending(&pendset); //获取[当前进程]的未决信号集,存放在pendset集合中
    //1-31信号                                                                          
    for(int i=1;i<=31;i++){                                                                                                      
      //判断信号i是否在pendset中,
      if(sigismember(&pendset,i))                                                                                                
        printf("1");                                                                                                             
      else                                                                                                                       
        printf("0");                                                                                                             
    }                                                                                                                            
    printf("\n");                                                                                                                
    sleep(1);                                                                                                                    
  }                                                                                                                                                                                                                                      
  return 0;                                                                                                                      
}  
[gjw@localhost 4-signal]$ ./signal_set 
0000000000000000000000000000000
0000000000000000000000000000000
0000000000000000000000000000000
0000000000000000000000000000000

案例2:

int main(){                                                                                                                      
  sigset_t myset;                
  //清空myset                                                                                                
  sigemptyset(&myset);                                                                                                           
  //将下面三个信号添加到myset集合中
  sigaddset(&myset,SIGINT); /*   ctrl+C   */                                                                                     
  sigaddset(&myset,SIGQUIT);/*   ctrl+\   */                                                                                     
  sigaddset(&myset,SIGKILL);                                                                                                     
  //将myset集合中的信号设为[阻塞]                                                                     
  sigprocmask(SIG_BLOCK,&myset,NULL);                                                                                            
                                                                                
  while(1){                                                                                                                      
    sigset_t pendset;                                                                                                            
    sigpending(&pendset); //读取当前进程的未决信号集
    //1-31                                                                                                                       
    for(int i=1;i<=31;i++){                                                                                                      
      if(sigismember(&pendset,i)) //判断i信号是否在penset中
        printf("1");                                                                                                             
      else                                                                                                                       
        printf("0");                                                                                                             
    }                                                                                                                            
    printf("\n");                                                                                                                
    sleep(1);                                                                                                                    
  }                                                                                                                              
                                                                                                                                 
  return 0;                                                                                                                      
}   
[gjw@localhost 4-signal]$ ./signal_set 
0000000000000000000000000000000
0000000000000000000000000000000
0000000000000000000000000000000
^C0100000000000000000000000000000    #点击ctrl+C
^\0110000000000000000000000000000    #点击ctrl+\
0110000000000000000000000000000
0110000000000000000000000000000
0110000000000000000000000000000
已杀死      #kill -9 signal_set的pid
程序解读:
	1.将ctrl+C,ctrl+\,kill -9引发的信号,放入myset阻塞信号集中
	2.调用ctrl+C,ctrl+\触发相应的信号,调用sigpending函数获取[当前进程的
	未决信号集],存放在pendset集合中
	3.for循环,使用sigismember函数判断i信号是否在pendset集合中
	4.调用kill -9杀死当前进程

猜你喜欢

转载自blog.csdn.net/weixin_36750623/article/details/83061785
今日推荐