linux c编程:信号(四) sigaction
signal 函数的使用方法简单,但并不属于 POSIX 标准,在各类 UNIX 平台上的实现不尽相同,因此其用途受到了一定的限制。而 POSIX 标准定义的信号处理接口是 sigaction 函数,其接口头文件及原型如下:
#include <signal.h>
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
◆ signum:要操作的信号。
◆ act:要设置的对信号的新处理方式。
◆ oldact:原来对信号的处理方式。
◆ 返回值:0 表示成功,-1 表示有错误发生。
struct sigaction 类型用来描述对信号的处理,定义如下:
struct sigaction
{
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
};
sa_handler:是一个函数指针,其含义与 signal 函数中的信号处理函数类似
sa_sigaction:另一个信号处理函数,它有三个参数,可以获得关于信号的更详细的信息。当 sa_flags 成员的值包含了 SA_SIGINFO 标志时,系统将使用 sa_sigaction 函数作为信号处理函数,否则使用 sa_handler 作为信号处理函数。
sa_flags 成员用于指定信号处理的行为,它可以是一下值的“按位或”组合。
◆ SA_RESTART:使被信号打断的系统调用自动重新发起。
◆ SA_NOCLDSTOP:使父进程在它的子进程暂停或继续运行时不会收到 SIGCHLD 信号。
◆ SA_NOCLDWAIT:使父进程在它的子进程退出时不会收到 SIGCHLD 信号,这时子进程如果退出也不会成为僵尸进程。
◆ SA_NODEFER:使对信号的屏蔽无效,即在信号处理函数执行期间仍能发出这个信号。
◆ SA_RESETHAND:信号处理之后重新设置为默认的处理方式。
◆ SA_SIGINFO:使用 sa_sigaction 成员而不是 sa_handler 作为信号处理函数
sa_mask: 这个参数指明了在信号处理函数执行过程中应该被阻止的信号的mask值。此外,触发这个handler的信号应该被阻止。
首先来看下sigaction的用法:
void ouch(int signum){
printf("received sig=%d\n",signum);
}
void signal_action_fun(){
struct sigaction act;
act.sa_handler=ouch;
sigemptyset(&act.sa_mask);
act.sa_flags=0;
sigaction(SIGINT,&act,NULL);
while(1){
printf("hello world!\n");
sleep(1);
}
}
当接受到终端发送的CTRL_C信号的时候,将会打印出该信号的值

继续来看下使用sa_sigaction的用法。
sa_sigaction函数中的siginfo_t 参数是一个如下定义的结构体:从中可以获取信号编号,进程ID等等信息
siginfo_t {
int si_signo; /*信号编号*/
int si_errno; /*错误号*/
int si_code; /*信号码*/
int si_trapno;/*导致硬件产生信号的trap号*/
pid_t si_pid; /*发送进程ID*/
uid_t si_uid; /*发送进程真实的用户ID*/
int si_status; /*退出值*/
clock_t si_utime; /*花费的用户时间*/
clock_t si_stime; /*花费的系统时间*/
sigval_t si_value; /*信号值*/
int si_int ; /*POSIX.1b 信号*/
void *si_ptr; /*POSIX.1b 信号*/
int si_overrun
int si_timerid
void *si_addr
long si_band
int si_fd;
short si_addr_lsb;
}
代码修改如下:
void ouch(int signum,siginfo_t *info,void *para){
printf("received sig=%d,the process id is %d\n",signum,info->si_pid);
printf("the uid is %d\n",info->si_uid);
}
void signal_action_fun(){
struct sigaction act;
sigemptyset(&act.sa_mask);
act.sa_flags=0;
act.sa_flags|=SA_SIGINFO; /*设置SA_SIGINFO表示使用sa_sigaction*/
act.sa_sigaction=ouch;
sigaction(SIGINT,&act,NULL);
while(1){
printf("hello world!\n");
sleep(1);
}
}
运行结果如下:在收到CTRL_C信号后,会打印出信号ID,进程ID以及用户ID。

linux c编程:信号(四) sigaction的更多相关文章
- Linux系统编程——信号
目录 信号的介绍 信号的机制 信号的编号 Linux常规信号一览表 信号的产生 终端按键产生信号 硬件异常产生信号 kill函数/命令产生信号 信号的操作函数 信号集设定 sigprocmask函数 ...
- linux系统编程--信号
信号的概念 man 7 siganl 查看man手册 信号在我们的生活中随处可见, 如:古代战争中摔杯为号:现代战争中的信号弹:体育比赛中使用的信号枪......他们都有共性:1. 简单 2. 不能 ...
- Linux系统编程—信号捕捉
前面我们学习了信号产生的几种方式,而对于信号的处理有如下几种方式: 默认处理方式: 忽略: 捕捉. 信号的捕捉,说白了就是抓到一个信号后,执行我们指定的函数,或者执行我们指定的动作.下面详细介绍两个信 ...
- Linux系统编程—信号集操作函数
先来回顾一下未决信号集是怎么回事. 信号从产生到抵达目的地,叫作信号递达.而信号从产生到递达的中间状态,叫作信号的未决状态.产生未决状态的原因有可能是信号受到阻塞了,也就是信号屏蔽字(或称阻塞信号集, ...
- Linux网络编程学习(四) -----守护进程的建立(第三章)
本文介绍一个例程daemon_init() #include <sys/types.h> #include <signal.h> #include <unistd.h&g ...
- Linux系统编程(24)——信号的生命周期
信号生命周期为从信号发送到信号处理函数的执行完毕. 对于一个完整的信号生命周期(从信号发送到相应的处理函数执行完毕)来说,可以分为三个重要的阶段,这三个阶段由四个重要事件来刻画:信号诞生:信号在进程中 ...
- Linux网络编程(四)
在linux网络编程[1-3]中,我们编写的网络程序仅仅是为了了解网络编程的基本步骤,实际应用当中的网络程序并不会用那样的.首先,如果服务器需要处理高并发访问,通常不会使用linux网络编程(三)中那 ...
- Linux高性能server编程——信号及应用
信号 信号是由用户.系统或者进程发送给目标进程的信息.以通知目标进程某个状态的改变或系统异常. Linux信号可由例如以下条件产生: 对于前台进程.用户能够通过输入特殊的终端字符来给它发送信号. ...
- linux系统编程之信号(三):信号安装、signal、kill,arise讲解
一,信号安装 如果进程要处理某一信号,那么就要在进程中安装该信号.安装信号主要用来确定信号值及进程针对该信号值的动作之间的映射关系,即进程将要处理哪个信号:该信号被传递给进程时,将执行何种操作. li ...
随机推荐
- 9.11排序与查找(一)——给定两个排序后的数组A和B,当中A的末端有足够的缓冲空间容纳B。将B合并入A并排序
/** * 功能:给定两个排序后的数组A和B,当中A的末端有足够的缓冲空间容纳B.将B合并入A并排序. */ /** * 问题:假设将元素插入数组A的前端,就必须将原有的元素向后移动,以腾出空间. ...
- HTTP Analyzer过滤器使用
HTTP Analyzer简单易用,真实抓包居家必备啊,上一次分享了Fiddler的过滤条件,这次介绍下这款软件的过滤,首先按照肯定是按照软件类型分类喽: 1.按照软件过滤: 这样只会显示chrome ...
- Python:Dom生成XML文件(写XML)
http://www.ourunix.org/post/327.html 在python中解析XML文件也有Dom和Sax两种方式,这里先介绍如何是使用Dom解析XML,这一篇文章是Dom生成XML文 ...
- asp.net core mvc视频A:笔记2-2.接收数据
传参方式一:使用内置方法传递 运行结果 其他获取方法 Session对象在HttpContext中 启用Session 使用Session 运行演示 传参方式二:数据绑定 普通类型(string).自 ...
- Atitit swt 4.3 4.4 4.5 新特性java attilax总结
Atitit swt 4.3 4.4 4.5 新特性java attilax总结 1. 4.5 Release - June 3, 20151 1.1. Older Releases1 2. SWT ...
- Windows下静态库、动态库的创建和调用过程
静态库和动态库的使用包括两个方面,1是使用已有的库(调用过程),2是编写一个库供别人使用(创建过程).这里不讲述过多的原理,只说明如何编写,以及不正确编写时会遇见的问题. //注:本文先从简单到复杂, ...
- hdu 3172 Virtual Friends(并查集,字典树)
题意:人与人交友构成关系网,两个人交友,相当于两个朋友圈的合并,问每个出两人,他们目前所在的关系网中的人数. 分析:用并查集,其实就是求每个集合当前的人数.对于人名的处理用到了字典树. 注意:1.题目 ...
- [译]GLUT教程 - 键盘
Lighthouse3d.com >> GLUT Tutorial >> Input >> Keyboard GLUT可以让应用程序自动监测键盘输入,包括普通按键和 ...
- 好文章收藏--五分钟理解一致性哈希算法(consistent hashing)
一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似.一致性哈希修正了CARP使用的简 单哈 ...
- JS Map对象
java和C#等高级语言中都有map这样的键值对,但是js里没有,我们需要这样的,该怎么做呢? 可以自己使用function封装一个map对象,如下所示 function Map() { this.k ...