信号集 & sigprocmask、sigpending

阻塞信号集/未决信号集

① 将某个信号放到阻塞信号集,这个信号将被忽略而不会被进程处理(该信号变成未决状态),换句话说,被阻塞的信号由于不能被递达而变成未决状态
② 直到阻塞解除后,该信号由未决状态变成递达状态,信号被处理。

信号集函数

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); // 屏蔽 or 解除

  • 参数
    how取值,假设当前的信号屏蔽字为mask
    - SIG_BLOCK:mask = mask|set 添加屏蔽字
    - SIG_UNBLOCK:mask = mask|~set 解除屏蔽字
    - SIG_SETMASK:mask = set 赋值操作
    set:传入的新的set
    oldset:保存之前的信号屏蔽字集合

int sigismember(const sigset_t *set, int signum); //判断set集合中是否存在signum信号

int sigpending(sigset_t *set); // 读取当前进程中处于未决状态的信号,放在传出参数set中


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杀死当前进程

功能描述:请编写一个程序,设置SIGINT和SIGQUIT信号,并在该程序中实现从文件中读取信息的操作,并保证在读取文件且只有在读取文件的过程中不会被发送的SIGINT和SIGQUIT信号所打断提示:在文件读取前阻塞信号,在文件读取后解除阻塞。

int main(){          
  int fd=open("/etc/profile",O_RDONLY);      
         
  //读取文件之前,将SIGINT/SIGQUIT信号设为阻塞
  sigset_t set;      
  sigemptyset(&set);      
  sigaddset(&set,SIGINT);        
  //sigaddset(&set,SIGQUIT);     
  sigprocmask(SIG_BLOCK,&set,NULL);          
         
  char buf[10];      
  //设为阻塞后,读取文件   
  while(read(fd,buf,sizeof(buf))!=0){        
    printf("%s",buf);
    //sleep(2);      
    memset(buf,0,sizeof(buf));   
  }      
/*         
  while(1){          
    pause();         
  }      
*/         
  //读取文件结束后,将SIGINT/SIGQUIT信号解除阻塞
  sigset_t uset;     
  sigemptyset(&uset);
  sigaddset(&uset,SIGINT);       
  //sigaddset(&uset,SIGQUIT);    
  sigprocmask(SIG_UNBLOCK,&set,NULL);    
      
  return 0;          
}

你可能感兴趣的:(Unix系统编程:,信号Signal)