lienhua34
2014-11-05

sigaction 函数跟 signal 函数一样,用于设置信号处理函数。此函数是用于取代 UNIX 早期版本使用的 signal 函数。UNIX 早期版本的 signal 函数在捕获到一个信号之后,就会自动将该信号的处理动作恢复为默认处理动作。于是,如果我们希望注册的信号处理函数长期生效,则需要在信号处理程序中再次调用 signal 函数注册一次。这样的操作太麻烦,而且在信号处理函数中再次调用 signal 注册信号处理函数之前可能又会产生该信号,而这个信号就会触发默认处理动作。

另外,signal 函数还有一个限制:不修改信号的处理方式就不能确定该信号的当前处理方式。这个限制在 sigaction 函数中不存在。

sigaction 函数的声明如下,

#include <signal.h>

int sigaction(int signo, const struct sigaction *restrict act, struct sigaction *restrict oact);

返回值:若成功则返回0,若出错则返回-1

其中,signo 参数即要检测或修改其处理动作的信号编号。如果 act 指针非空,则要修改该信号的处理动作。如果 oact 指针非空,则由 oact 指针返回该信号的上一个动作。
sigaction 函数的参数中使用的结构体 struct sigaction 的声明如下,

struct sigaction {
void (*sa_handler)(int);
sigset_t sa_mask;
int sa_flags;
void (*sa_sigaction)(int, siginfo_t *, void *);
};

该结构体各个字段的说明如下:

  • sa_handler:信号处理函数的指针。
  • sa_mask:在调用该信号的处理函数期间进程要阻塞的信号集。
  • sa_flags:指定信号进行处理的各个选项,关于具体的选项,可以参考sigaction 函数的手册。
  • sa_sigaction:替代的信号处理函数,如果sa_flags 设置了SA_SIGINFO,则会调用该信号处理函数;否则调用sa_handler。

我们来看一个例子,

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h> void
print_mask(const char *str)
{
sigset_t sigset;
int errno_save; errno_save = errno;
if (sigprocmask(, NULL, &sigset) < ) {
printf("sigprocmask error: %s\n", strerror(errno));
exit(-);
}
printf("%s", str);
if (sigismember(&sigset, SIGALRM)) {
printf("SIGALRM ");
}
if (sigismember(&sigset, SIGINT)) {
printf("SIGINT ");
}
printf("\n");
errno = errno_save;
} static void
sig_alrm(int signo)
{
printf("received SIGALRM\n");
print_mask("in sig_alrm: ");
} int
main(void)
{
struct sigaction sact; sact.sa_handler = sig_alrm;
sact.sa_flags = ;
sigemptyset(&sact.sa_mask);
sigaddset(&sact.sa_mask, SIGINT);
if (sigaction(SIGALRM, &sact, NULL) < ) {
printf("sigaction error: %s\n", strerror(errno));
exit(-);
} print_mask("in main before alarm: ");
alarm();
pause();
print_mask("in main after alarm: ");
exit();
}

在上面的 sigactiondemo.c 程序中,我们调用 sigaction 函数设置了信号 SIGALRM 的处理函数,而在 sigaction 函数的参数 act 的sa_mask 字段中添加了信号 SIGINT,表示调用信号 SIGALRM 的处理函数期间,进程阻塞信号 SIGINT。编译该程序,生成并执行可执行文件 sigactiondemo,

lienhua34:demo$ gcc -o sigactiondemo sigactiondemo.c
lienhua34:demo$ ./sigactiondemo
in main before alarm:
received SIGALRM
in sig_alrm: SIGALRM SIGINT
in main after alarm:

从上面的运行结果,我们看到在 SIGALRM 信号产生之前,进程没有屏蔽信号 SIGINT 和 SIGALRM,而在信号 SIGALRM 的处理函数中,进程的信号屏蔽字中包含了 SIGINT 和 SIGALRM,而在调用 SIGALRM 的信号处理函数之后,进程的信号屏蔽字复原为调用信号处理屏蔽字之前。(说明:在调用 sigaction 函数注册的信号处理函数期间,系统会自动将该信号也加入信号屏蔽字中,除非设置 sigaction 函数的 act 参数的sa_flags为SA_NODEFER。)

(done)

UNIX环境编程学习笔记(25)——信号处理进阶学习之 sigaction 函数的更多相关文章

  1. UNIX基础知识--<<UNIX 环境编程>>读书笔记

    1 shell程序就是位于应用软件与系统调用之间的程序   每个用户登录系统,系统就会为用户分配shell (用户的登录的口令文件 在  /etc/passwd 2 ls filename  运行原理 ...

  2. UNIX环境编程学习——反思认识

     学习情况: 有关UNIX系统环境编程的学习时间用来非常长的时间.可是感觉效果还是不是太好,在中间经过了期末考试.用来非常长的时间用来学习专业课.就将该过程的学习放到了一边上,放假以后又回家造成了 ...

  3. IOS学习笔记25—HTTP操作之ASIHTTPRequest

    IOS学习笔记25—HTTP操作之ASIHTTPRequest 分类: iOS2012-08-12 10:04 7734人阅读 评论(3) 收藏 举报 iosios5网络wrapper框架新浪微博 A ...

  4. Django:学习笔记(7)——模型进阶

    Django:学习笔记(7)——模型进阶 模型的继承 我们在面向对象的编程中,一个很重要的的版块,就是类的继承.父类保存了所有子类共有的内容,子类通过继承它来减少冗余代码并进行灵活扩展. 在Djang ...

  5. amazeui学习笔记二(进阶开发5)--Web 组件开发规范Rules

    amazeui学习笔记二(进阶开发5)--Web 组件开发规范Rules 一.总结 1.见名知意:见那些class名字知意,见函数名知意,见文件名知意 例如(HISTORY.md Web 组件更新历史 ...

  6. amazeui学习笔记二(进阶开发4)--JavaScript规范Rules

    amazeui学习笔记二(进阶开发4)--JavaScript规范Rules 一.总结 1.注释规范总原则: As short as possible(如无必要,勿增注释):尽量提高代码本身的清晰性. ...

  7. amazeui学习笔记二(进阶开发3)--HTML/CSS规范Rules

    amazeui学习笔记二(进阶开发3)--HTML/CSS规范Rules 一.总结 1.am:以 am 为命名空间 2.模块状态: {命名空间}-{模块名}-{状态描述} 3.子模块: {命名空间}- ...

  8. amazeui学习笔记二(进阶开发2)--Web组件简介Web Component

    amazeui学习笔记二(进阶开发2)--Web组件简介Web Component 一.总结 1.amaze ui:amaze ui是一个web 组件, 由模板(hbs).样式(LESS).交互(JS ...

  9. amazeui学习笔记二(进阶开发1)--项目结构structure

    amazeui学习笔记二(进阶开发1)--项目结构structure 一.总结 1.项目结构:是说的amazeui在github上面的项目结构,二次开发amazeui用 二.项目结构structure ...

  10. 线段树学习笔记(基础&进阶)(一) | P3372 【模板】线段树 1 题解

    什么是线段树 线段树是一棵二叉树,每个结点存储需维护的信息,一般用于处理区间最值.区间和等问题. 线段树的用处 对编号连续的一些点进行修改或者统计操作,修改和统计的复杂度都是 O(log n). 基础 ...

随机推荐

  1. sphinx增量索引和主索引来实现索引的实时更新

    项目中文章的信息内容因为持续有新增,而文章总量的基数又比较大,所以做搜索的时候,用了主索引+增量索引这种方式来实现索引的实时更新. 实现原理: 1. 新建一张表,记录一下上一次已经创建好索引的最后一条 ...

  2. 【Lua】环境安装与HelloWorld

    emmmm...看了W3C和菜鸟教程的环境安装,感觉还是省略了一些东西的. 记录一下在Windows上怎么开始编写Lua的学习过程. 环境安装 直接在Lua官网上找到最新版的下载地址,根据说明下载Lu ...

  3. python3.6使用mysql

    因为MySQLdb不支持python3,需要导入pymysql 可以选择pip 安装pymysql,或者pycharm安装 [File] >> [settings] >> [P ...

  4. JavaScript JSON 数据处理

    在JavaScript 也自带了 JSON 格式的处理 <!doctype html> <html> <script> var test_json_str = { ...

  5. js中表单数据序列化方式

    一共有以下三种: var obj1 = $('#queryForm').serialize(); var obj2 = $('#queryForm').serializeArray(); var ob ...

  6. Linux用户及用户组管理命令

    一,组操作 1.创建组 groupadd  test 增加一个test组 2.修改组 groupmod -n test2  test 将test组的名子改成test2  3.删除组 groupdel ...

  7. linux系统管理命令(五)

    [教程主题]:1.系统管理命令 [1.1]用户和组管理 在Linux操作系统中,任何文件都归属于某一特定的用户,而任何用户都隶属于至少一个用户组.用户是否有权限对某文件进行访问.读写以及执行,受到系统 ...

  8. 读取 classes下的配置文件

    调用: Configure.getValue("discount.strategy.class"); 配置类: package com.util; import com.sun.j ...

  9. HashSet与TreeSet 区别

    HashSetHashSet有以下特点 不能保证元素的排列顺序,顺序有可能发生变化 不是同步的 集合元素可以是null,但只能放入一个null当向HashSet集合中存入一个元素时,HashSe ...

  10. css3学习系列之初识 transform (一)

    一.transform是哈? 从字面意思来看 transform的含义是:改变,使…变形:转换,对 没错 就是变形 变形当有 放大缩小 东倒 西歪,刚好css3中 transform 也出这个 放几个 ...