sigaction 用法实例

简介: sigaction函数的功能是检查或修改与指定信号相关联的处理动作(可同时两种操作)。   他是POSIX的信号接口,而signal()是标准C的信号接口(如果程序必须在非POSIX系统上运行,那么就应该使用这个接口) 给信号signum设置新的信号处理函数act, 同时保留该信号原有的信...

sigaction函数的功能是检查或修改与指定信号相关联的处理动作(可同时两种操作)。

 

他是POSIX的信号接口,而signal()是标准C的信号接口(如果程序必须在非POSIX系统上运行,那么就应该使用这个接口)

给信号signum设置新的信号处理函数act, 同时保留该信号原有的信号处理函数oldact

intsigaction(int signo,conststruct sigaction*restrict act,

             struct sigaction*restrict oact);

 

结构sigaction定义如下:

structsigaction{
  void (*sa_handler)(int);
   sigset_t sa_mask;
  int sa_flag;
  void (*sa_sigaction)(int,siginfo_t*,void*);
};

sa_handler字段包含一个信号捕捉函数的地址

sa_mask字段说明了一个信号集,在调用该信号捕捉函数之前,这一信号集要加进进程的信号屏蔽字中。仅当从信号捕捉函数返回时再将进程的信号屏蔽字复位为原先值。

sa_flag是一个选项,主要理解两个

SA_NODEFER:  当信号处理函数正在进行时,不堵塞对于信号处理函数自身信号功能。
SA_RESETHAND:当用户注册的信号处理函数被执行过一次后,该信号的处理函数被设为系统默认的处理函数。

SA_SIGINFO 提供附加信息,一个指向siginfo结构的指针以及一个指向进程上下文标识符的指针

最后一个参数是一个替代的信号处理程序,当设置SA_SIGINFO时才会用他。

 

 

 

 

使用示例为:

 

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
 
  1. #include <stdio.h>  
  2. #include <signal.h>  
  3.   
  4.   
  5. void WrkProcess(int nsig)  
  6. {  
  7.         printf("WrkProcess .I get signal.%d threadid:%d/n",nsig,pthread_self());  
  8.   
  9.   
  10.         int i=0;  
  11.         while(i<5){  
  12.                 printf("%d/n",i);  
  13.                 sleep(1);  
  14.                 i++;  
  15.         }  
  16. }  
  17.   
  18. int main()  
  19. {  
  20.         struct sigaction act,oldact;  
  21.         act.sa_handler  = WrkProcess;  
  22. //      sigaddset(&act.sa_mask,SIGQUIT);  
  23. //      sigaddset(&act.sa_mask,SIGTERM)  
  24.         act.sa_flags = SA_NODEFER | SA_RESETHAND;    
  25. //        act.sa_flags = 0;  
  26.   
  27.         sigaction(SIGINT,&act,&oldact);  
  28.   
  29.         printf("main threadid:%d/n",pthread_self());  
  30.   
  31.         while(1)sleep(5);  
  32.   
  33.         return 0;  
  34. }  

 

 

 

 

1)执行改程序时,ctrl+c,第一次不会导致程序的结束。而是继续执行,当用户再次执行ctrl+c的时候,程序采用结束。

 

2)如果对程序稍微进行一下改动,则会出现另外一种情况。

改动为:act.sa_flags = SA_NODEFER;

经过这种改变之后,无论对ctrl+d操作多少次,程序都不会结束。

 

3)下面如果再对程序进行一次改动,则会出现第三种情况。

 

For example:  act.sa_flags = 0;

在执行信号处理函数这段期间,多次操作ctrl+c,程序也不会调用信号处理函数,而是在本次信号处理函数完成之后,在执行一次信号处理函数(无论前面产生了多少次ctrl+c信号)。

如果在2)执行信号处理函数的过程中,再次给予ctrl+c信号的时候,会导致再次调用信号处理函数。

4)如果在程序中设置了sigaddset(&act.sa_mask,SIGQUIT);程序在执行信号处理函数的过程中,发送ctrl+/信号,程序也不会已经退出,而是在信号处理函数执行完毕之后才会执行SIGQUIT的信号处理函数,然后程序退出。如果不添加这项设置,则程序将会在接收到ctrl+/信号后马上执行退出,无论是否在ctrl+c的信号处理函数过程中。

 

 

原因如下:

1)情况下,第一次产生ctrl+c信号的时候,该信号被自己设定的信号处理函数进行了处理。在处理过程中,由于我们设定了SA_RESETHAND标志位,又将该信号的处理函数设置为默认的信号处理函数(系统默认的处理方式为IGN),所以在第二次发送ctrl+d信号的时候,是由默认的信号处理函数处理的,导致程序结束;

2)情况下,我们去掉了SA_RESETHAND了标志位,导致程序中所有的ctrl+d信号均是由我们自己的信号处理函数来进行了处理,所以我们发送多少次ctrl+c信号程序都不会退出;

3)情况下,我们去掉了SA_NODEFER标志位。程序在执行信号处理函数过程中,ctrl+c信号将会被阻止,但是在执行信号处理函数期发送的ctrl+c信号将会被阻塞,知道信号处理函数执行完成,才有机会处理信号函数执行期间产生的ctrl+c,但是在信号函数执行产生的多次ctrl+c,最后只会产生ctrl+c。2)情况下,由于设置了SA_NODEF,ctrl+c信号将不会被阻塞。所以能够并行执行下次的信号处理函数。

4)情况下,我们是设置了在执行信号处理函数过程中,我们将屏蔽该信号,当屏蔽该信号的处理函数执行完毕后才会进行处理该信号。

 

 

 

附:

当我们按下ctrl+c的时候,操作为:向系统发送SIGINT信号,SIGINT信号的默认处理,退出程序。

当我们按下ctrl+/的时候,操作为:向系统发送SIGQUIT信号,该信号的默认处理为退出程序。

 

 

FROM:  http://blog.csdn.net/jiang1013nan/article/details/5409684

 

参考: sigaction函数解析

http://blog.chinaunix.net/uid-1877180-id-3011232.html

目录
相关文章
|
开发框架 Ubuntu 应用服务中间件
FastCGI与spawn-fcgi安装与配置
FastCGI与spawn-fcgi安装与配置
1048 0
FastCGI与spawn-fcgi安装与配置
|
安全 小程序 Linux
Linux中信号是什么?Ctrl + c后到底为什么会中断程序?
信号在进程的学习中是一个非常好用的存在,它是软件层次上对中断机制的一种模拟,是异步通信方式,同时也可以用来检测用户空间到底发生了什么情况,然后系统知道后就可以做出相应的对策。
485 6
|
Unix Linux 开发工具
Linux 命令 `ctags`:代码导航的利器
`ctags` 是一款Unix工具,用于生成代码标签,方便在Vim、Emacs等编辑器中快速跳转到函数、变量定义。在Linux上,可通过包管理器安装。使用`ctags -R`生成`tags`文件,然后在Vim中用`Ctrl+]`跳转,`Ctrl+T`返回。Emacs则使用`M-.`和`M-,`。`ctags`可自定义语言映射和排除规则,是提升编程效率的利器。
|
自然语言处理 编译器 Linux
C语言进阶⑳(程序环境和预处理)(#define定义宏+编译+文件包含)(下)
C语言进阶⑳(程序环境和预处理)(#define定义宏+编译+文件包含)
170 0
|
存储 C语言 C++
C++遍历文件夹获取各文件名称并筛选指定格式类型的文件或具有特定名称的文件
C++遍历文件夹获取各文件名称并筛选指定格式类型的文件或具有特定名称的文件
259 1
Application provided invalid, non monotonically increasing dts to muxer in stream
Application provided invalid, non monotonically increasing dts to muxer in stream
789 0
Application provided invalid, non monotonically increasing dts to muxer in stream
|
存储 C语言
【C语言】 --- getopt()函数的使用简析
【C语言】 --- getopt()函数的使用简析
244 0
|
弹性计算 运维 监控
如何解决 Linux 内核调测两大难题:内存被改与内存泄露
一直以来,内核内存调测领域一直持续存在着两大行业难题: "内存被改" 和 "内存泄漏"。内存问题行踪诡异、飘忽不定,在 Linux 内核的调测问题中,是最让开发者头疼的 bug 之一,因为内存问题往往发生故障的现场已经是第 N 现场了,尤其是在生产环境上出现,截止目前并没有一个很有效的方案能够进行精准的线上 debug,导致难以排查、耗时耗力。
672 0
如何解决 Linux 内核调测两大难题:内存被改与内存泄露
使用dpkg-deb查看deb文件的安装目录
使用dpkg-deb查看deb文件的安装目录
1496 0