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

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

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

int sigaction(int signo,const struct sigaction *restrict act,

struct sigaction *restrict oact);

结构sigaction定义如下:

struct sigaction{
  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_INTERRUPT 由此信号中断的系统调用不会自动重启
SA_RESTART 由此信号中断的系统调用会自动重启

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

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

例子:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void show_handler(int sig)
{
    printf("I got signal %d\n", sig);
    int i;
    for(i = 0; i < 5; i++) {
        printf("i = %d\n", i);
        sleep(1);
    }
}

int main(void)
{
    int i = 0;
    struct sigaction act, oldact;
    act.sa_handler = show_handler;
    sigaddset(&act.sa_mask, SIGQUIT); //见注(1)
    act.sa_flags = SA_RESETHAND | SA_NODEFER; //见注(2)
    //act.sa_flags = 0; //见注(3)

sigaction(SIGINT, &act, &oldact);
    while(1) {
        sleep(1);
        printf("sleeping %d\n", i);
        i++;
    }
}

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

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

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

最新文章

  1. SDK的制作详解
  2. WebApi传参总动员(二)
  3. UITableview cell 的多选
  4. 使用 autoconf
  5. Oracle中使用escape关键字实现like匹配特殊字符,以及&amp;字符的转义
  6. HDU 2553 N皇后问题(dfs)
  7. 最近整理AI相关感想
  8. 阿里云学习之IOT物联网套件(客户端与服务端的后台数据传输)
  9. 前端的UI设计与交互之反馈示篇
  10. LeetCode笔记:39. Combination Sum
  11. JAVA内存分配与回收策略
  12. Servlet开发 中使用 log4jdbc 记录 hibernate 的 SQL信息
  13. 德州扑克AI--Programming Poker AI(译)
  14. Node学习笔记:建立TCP服务器和客户端之间的通信
  15. 在同一台电脑安装python 2 和3,并且怎样安装各自的pip和模块
  16. webpack提取库
  17. Unity Animation需要Inspector右键打开Debug模式,然后勾选Legacy,最后再Inspector右键打开Normal
  18. 常用网络命令(windows)
  19. 转载 ORACLE中实现表变量的方法
  20. 2014 百度之星 题解 1004 Labyrinth

热门文章

  1. 如何利用Fluxion诱惑目标用户获取WPA密码
  2. Dubbo应用启动与停止脚本,超具体解析
  3. B+树在NTFS文件系统中的应用
  4. SQL2012 尝试读取或写入受保护的内存。这通常指示其它内存已损坏
  5. LoadRunner系列之—-03 用Java Vuser协议编写接口测试脚本
  6. poj2488--A Knight&amp;#39;s Journey(dfs,骑士问题)
  7. 大话设计模式C++实现-第19章-组合模式
  8. 树莓派的PWM脉宽调制功能介绍
  9. Error 99 connecting to 192.168.3.212:6379. Cannot assign requested address
  10. Delphi中accesss实现树形结构查询系统(一次性生成比较方便)