信号捕捉函数 & sigaction | 临时信号屏蔽集

本文深入探讨了sigaction函数的用途及其在信号处理中的角色,特别是关于临时信号屏蔽集sa_mask的理解。通过代码示例展示了如何使用sigaction注册信号处理函数,以及临时屏蔽信号的具体行为和效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

sigaction

用途
① 注册signum信号处理函数,并设置 ”临时信号屏蔽集“(本文详细对此进行了详细分析)
② 注册signum信号处理函数,接收数据—https://blog.youkuaiyun.com/weixin_36750623/article/details/91468432


临时信号屏蔽的本质是什么?
① 假设信号A在临时信号屏蔽集sa_mask中( 设signum != A )
② 当signum信号发生时,将进入注册的信号处理函数
③ 在信号处理函数执行过程中,假如此时有信号A产生,那么信号A将被忽略(信号A变成未决状态)
④ 当信号处理函数执行完成后,未决的信号A将被递达,信号A的处理函数才被调用
注意:尽管信号A产生了多次,当信号处理函数执行完成后,信号A的处理函数仅仅被执行一次!

说了那么多废话,临时信号屏蔽的个人理解见下:
    (1) 在信号处理函数执行过程中,屏蔽集合sa_mask中包含的信号将会被暂时屏蔽!
    (2) 被暂时屏蔽的信号最终仍然会递达!

int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
struct sigaction {  // 第二参数 act

 int sa_flags; //0 —> sa_handler     SA_SIGINFO —> sa_sigaction
 void (*sa_handler)(int); //信号处理函数[不接受额外数据]
 void (*sa_sigaction)(int, siginfo_t *, void *); //信号处理函数[能接受额外数据];sigqueue
 
 sigset_t sa_mask;  //临时屏蔽信号集

 void (*sa_restorer)(void); //废弃,一般不使用
};

sa_flags决定了使用哪个信号处理函数
    [ sa_flags=0] --->sa_handler
    [ sa_flags=SA_SIGINFO] --->sa_sigaction


示例代码: 临时屏蔽的信号(使用act.sa_handler)

程序测试功能

  1. 临时屏蔽的信号
  2. 不带数据的信号处理函数:act.sa_flags=0 和 act.sa_handler

程序运行分析

  1. 注释 sigaddset(&act.sa_mask,SIGQUIT):即不暂时阻塞Ctrl+\产生的SIGQUIT信号 ;连续按Ctrl+C多次,接着按ctrl+\,程序立即被Ctrl+\产生的SIGQUIT信号终止
  2. 不注释 sigaddset(&act.sa_mask,SIGQUIT):即暂时阻塞Ctrl+\产生的SIGQUIT信号 ;连续按Ctrl+C多次,接着按ctrl+\,程序[不会]立即被Ctrl+\产生的SIGQUIT信号终止(此时代码执行到sleep(3); 语句),直到handler信号处理函数执行完毕后,才执行SIGQUIT信号处理函数。

总结

  1. 通过上面两个程序执行效果对比,临时阻塞信号的含义是:如果代码进入到其他信号的处理函数,并且还在运行;处于临时阻塞信号集中的信号处理函数将被忽略变为未决状态;必须等到其他信号的处理函数执行完成后,才去变成抵达状态而调用相应的信号处理函数。
  2. 因此,只是临时屏蔽的作用,和前面讲的阻塞信号集合是不同的,此处并不是真正的屏蔽。
void handler(){    
  printf("handler: Ctrl+C      \n");       
  sleep(3);        
  printf("handler: wake up     \n");       
}      
       
int main(){   
  struct sigaction act;        
  
  act.sa_flags=0; //表示使用act.sa_handler形式的信号处理函数 
  act.sa_handler=handler;          
         
  sigemptyset(&act.sa_mask); //清空sa_mask
  //sigaddset(&act.sa_mask,SIGQUIT);   //注释?不注释?    
  
  sigaction(SIGINT,&act,NULL); 
  while(1){        
    sleep(1); 
  } 
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值