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 ...
随机推荐
- 你真的了解装箱(Boxing)和拆箱(Unboxing)吗?
所谓装箱就是装箱是将值类型转换为 object 类型或由此值类型实现的任一接口类型的过程.而拆箱就是反过来了.很多人可能都知道这一点,但是是否真的就很了解boxing和unboxing了呢?可以看下下 ...
- LeetCode题目:Minimum Path Sum
原题地址:https://leetcode.com/problems/minimum-path-sum/ 大意:给出一个二维数组(int类型),求出从左上角到右下角最短的路径. 解决方法:动态规划 c ...
- 【Mysql】 你会用 information_schema吗?
示例 select * from information_schema.views 其中的views可以替换成以下的字段,以下未列举的一般的数据库操作工具,在information_schema后输入 ...
- storm - 经常使用命令
1.提交Topologies 命令格式:storm jar [jar路径] [拓扑包名.拓扑类名][stormIP地址][stormport][拓扑名称][參数] eg: storm jar /hom ...
- linux 进程的 5 大段
BSS段:BSS段(bss segment)通常是指用来存放程序中数据段:数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域.数据段属于静态内存分配. 数据段:数 ...
- MQTT--Mosquitto的配置文件
Mosquitto的配置文件存放在/etc/mosquitto/mosquitto.conf 配置文件具体的配置内容为: # ===================================== ...
- nightwatch-js -- test group
Test group 可以将你的测试脚本划分到组中,并根据需要运行它们.要将测试组合在一起,只需将它们放在相同的子文件夹中,文件夹的名字即是组的名字.例如:lib/├── selenium-serve ...
- WebStorm初次使用
1. ctrl + / : 单行注释2. ctrl + shift + / : 块注释 3:展开当前函数代码:Ctrl+“+”,收起当前代码:Ctrl+“-” 4:全局查找: Ctrl+Shift+F ...
- Redis, Memcache, Mysql差别
在使用Redis过程中,我们发现了不少Redis不同于Memcached.也不同于MySQL的特征. (本文主要讨论Redis未启用VM支持情况) 1. Schema MySQL: 需事先设计 Mem ...
- centos7 配置ssh 免密码登陆
我只有一台机器,是因为要配置hadoop分布式环境用,需要配置ssh 两个用户: zhangxs, root 首先在切换到zhangxs用户下 执行[ ssh-keygen -t rsa] [zhan ...