sigaction实例

本文详细解析了在C/C++编程中如何使用`signal`库进行信号处理,包括信号集的创建、信号处理函数的定义、信号处理选项的设置以及信号处理过程中的行为变化。通过具体实例展示了不同信号处理选项对信号响应的影响,如`SA_RESETHAND`和`SA_NODEFER`的作用,以及如何避免信号丢失的情况。

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


  1. struct sigaction{  
  2.     void (*sa_handler)(int);  
  3.     //在调用前加入信号屏蔽字,仅当信号捕捉函数返回时再将进程的信号屏蔽字复位为原先值*/  
  4.     sigset_t sa_mask;  
  5.     //Signal options  
  6.     int flags;  
  7.     //结构中还有一个参数,不懂。  
  8. }  
 
  1. #include <stdio.h>  
  2. #include <signal.h>  
  3. #include <unistd.h>  
  4. void show_handler(int sig)  
  5. {  
  6.     printf("I got signal %d\n", sig);  
  7.     int i;  
  8.     for(i = 0; i < 5; i++) {  
  9.         printf("i = %d\n", i);  
  10.         sleep(1); //for inputting interupt signal  
  11.     }  
  12. }  
  13.   
  14. int main(void)  
  15. {  
  16.     int i = 0;  
  17.     struct sigaction act, oldact;  
  18.     act.sa_handler = show_handler;  
  19.     sigaddset(&act.sa_mask, SIGQUIT); //(1)加入信号集,屏蔽"CTRL+\"  
  20.     act.sa_flags = SA_RESETHAND | SA_NODEFER; //(2)if signal got,set to SIG_DFL   
  21.   
  22.     //act.sa_flags = 0; //(3)  
  23.     //sigprocmask(SIG_BLOCK,&act.sa_mask,NULL);/*This can be used for add sigset mask*/  
  24.     sigaction(SIGINT, &act, &oldact);  
  25.     while(1) {  
  26.         sleep(1);  
  27.         printf("sleeping %d\n", i);  
  28.         i++;  
  29.     }  
  30. }  
 

 

结果如下:


(1)第一种情况,执行"CTRL+C", 在中断处理函数后再执行"CTRL+C"

$./a.out
sleeping 0
I got signal 2 /*CTRL+C*/
i = 0
i = 1
i = 2
i = 3
i = 4
sleeping 1
sleeping 2
sleeping 3
sleeping 4 /*CTRL+C结束*/

说明:第二次"CTRL+C",由于act.sa_flags = SA_RESETHAND | SA_NODEFER 。SA_RESETHAND: 信号发给进程后,把信号处理器复位为缺省值SIG_DFL,所以第二次按"Ctrl+C"时, 信号处理器已经复位为SIG_DFL,对SIGINT来说,缺省动作就是终止进程。

 

 

(2)注:如果在信号SIGINT(Ctrl + C)的信号处理函数show_handler执行过程中,本进程收到信号SIGQUIT(Crt+\),将阻塞该信号,直到show_handler执行结束才会处理信号SIGQUIT,见如下结果

$./a.out
sleeping 0
sleeping 1
I got signal 2 /*CTRL+C*/
i = 0
i = 1
i = 2 /*CTRL+\*/
i = 3
i = 4
Quit

 


(3)第三种情况:"CTRL+C", "CTRL+C", "CTRL+\"

改act.sa_flags = SA_RESETHAND | SA_NODEFER;->act.sa_flags =SA_NODEFER;

[root@FPC10 zhisxu]# ./a.out
sleeping 0
I got signal 2 /*CTRL+C*/
i = 0
i = 1
I got signal 2 /*CTRL+C*/
i = 0
i = 1 /*somewhere here*/
i = 2 /*CTRL+\*/
i = 3
i = 4
i = 2
i = 3
i = 4
Quit


sigaction.sa_flags    控制内核对该信号的处理标记
SA_NODEFER 一般情况下, 当信号处理函数运行时,内核将阻塞<该给定信号 -- SIGINT>。但是如果设置了SA_NODEFER标记, 那么在该信号处理函数运行时,内核将不会阻塞该信号。 SA_NODEFER是这个标记的正式的POSIX名字(还有一个名字SA_NOMASK,为了软件的可移植性,一般不用这个名字)    
SA_RESETHAND 当调用信号处理函数时,将信号的处理函数重置为缺省值。 SA_RESETHAND是这个标记的正式的POSIX名字(还有一个名字SA_ONESHOT,为了软件的可移植性,一般不用这个名字)
SA_SIGINFO 信号处理函数是带有三个参数的
sa_sigaction

*** 如果不需要重置该给定信号的处理函数为缺省值;并且不需要阻塞该给定信号(无须设置sa_flags标志),那么必须将sa_flags清零,否则运行将会产生段错误。但是sa_flags清零后可能会造成信号丢失!

注: 阻塞的意思是延迟相应信号

 

 

原文地址:http://hi.baidu.com/xu_zhisheng/blog/item/82cbdfd7ab12872607088bdc.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值