函数函数sigaction、signal
函数函数sigaction
1. 函数sigaction原型:
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
分析:
- 参数 signum :要捕获的信号。
- 参数act:truct sigaction 结构体,后面具体讲解传入参数,新的处理方式
- 参数oldact:返回旧的 struct sigaction 结构体,传出参数,旧的处理方式
1.2 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 : 不带附加参数的信号处理函数指针
- sa_sigaction: 带有附加参数的信号处理函数指针(两个信号处理函数指针只能二选一)
- sa_mask: 在执行信号处理函数时,应该屏蔽掉哪些信号
- sa_flags: 用于控制信号行为,它的值可以是下面选项的组合。
- SA_SIGINFO:如果指定该选项,则向信号处理函数传递参数(这时应该使用 sa_sigaction 成员而不是 sa_handler).
- sa_restorer:该成员在早期是用来清理函数栈的,如今已被废弃不用。
注意:sa_flags 的选项比较多,大部分可又自己做实验验证,有些是需要额外的知识,比如 SA_ONESTACK 和 SA_RESTART,这些放到后面讲解。本节示例中,只需要把 sa_flags 设置为 0 即可。
信号捕捉特性:
- 进程正常运行时,默认PCB有一个信号屏蔽字,假定为☆,它决定了进程自动屏蔽哪些信号,当注册了某个信号步捕捉函数,捕捉到该信号以后,要调用该函数,而该函数有可能执行很长时间,在这期间所屏蔽的信号不由☆指定,而由sa_mask来指定,调用完信号处理函数,再恢复为☆。
- xxx信号捕捉函数执行期间,XXX信号自动屏蔽。
- 阻塞的常规信号不支持排队,产生多次只记录一次(后32个实时信号支持排队)
1. 测试代码:
#include<stdio.h>
#include<signal.h>
#include<stdlib.h>
#include<unistd.h> void docatch(int signo)
{
printf("%d signal is catch\n", signo);
} int main()
{
int ret;
struct sigaction act;
act.sa_handler = docatch;
sigemptyset(&act.sa_mask);
sigaddset(&act.sa_mask, SIGQUIT);
act.sa_flags = ; //默认属性:信号捕捉函数执行期间,自动屏蔽本信号
ret = sigaction(SIGINT, &act, NULL);
if(ret < )
{
perror("sigaction error");
exit();
}
while()
sleep();
return ;
}
输出结果:

2. 测试代码:
#include<stdio.h>
#include<signal.h>
#include<stdlib.h>
#include<unistd.h> void docatch(int signo)
{
printf("%d signal is catch\n", signo);
sleep();
printf("--------------finish-\n");
} int main()
{
int ret;
struct sigaction act;
act.sa_handler = docatch;
sigemptyset(&act.sa_mask);
sigaddset(&act.sa_mask, SIGQUIT);
act.sa_flags = ;
ret = sigaction(SIGINT, &act, NULL);
if (ret < )
{
perror("sigaction error");
exit();
}
while ()
sleep();
return ;
}
输出结果:

3. 测试代码:
#include <unistd.h>
#include <signal.h>
#include <stdio.h> void printsigset(const sigset_t *set)
{
for (int i = ; i <= ; i++)
{
if (i == ) putchar(' ');
if (sigismember(set, i) == )
putchar('');
else
putchar('');
}
puts("");
} void handler(int sig)
{
if (sig == SIGTSTP)
printf("hello SIGTSTP\n");
if (sig == SIGINT)
printf("hello SIGINT\n");
sleep();
sigset_t st;
sigpending(&st);
printsigset(&st);
} int main()
{
printf("I'm %d\n", getpid());
struct sigaction act, oldact;
act.sa_handler = handler; // 设置普通信号处理函数
sigemptyset(&act.sa_mask); // 向 sa_mask 中添加 SIGINT
sigaddset(&act.sa_mask, SIGINT);
act.sa_flags = ; // 先置 0 sigaction(SIGTSTP, &act, &oldact);
sigaction(SIGINT, &act, &oldact); while ()
{
write(STDOUT_FILENO, ".", );
pause();
}
return ;
}
输出结果:

分析:
- 当程序运行的时候,Ctrl C 进入 handler,然后立即 Ctrl Z 发现 handler 还未执行完就被 SIGTSTP 打断.
- 当程序运行的时候,Ctrl Z 进入 handler,然后立即 Ctrl C 发现并不会被 SIGINT 打断,这是因为该 handler 注册的时候被设置了 SA_MASK = SIGINT。最后 handler 结束的时候打印了未决信号集,发现里头有 SIGINT。所以 handler 结束后,又去继续对 SIGINT 进行处理。
函数函数sigaction、signal的更多相关文章
- signal函数、sigaction函数及信号集(sigemptyset,sigaddset)操作函数
信号是与一定的进程相联系的.也就是说,一个进程可以决定在进程中对哪些信号进行什 么样的处理.例如,一个进程可以忽略某些信号而只处理其他一些信号:另外,一个进程还可以选择如何处理信号.总之,这些总与特定 ...
- signal函数:void (*signal(int,void(*)(int)))(int);
http://blog.chinaunix.net/uid-20178794-id-1972862.html signal函数:void (*signal(int,void(*)(int)))(int ...
- 简单理解函数声明(以signal函数为例)
这两天遇到一些声明比较复杂的函数,比如signal函数,那我们先简单说说signal函数的用法:(参考<c陷阱与缺陷>) [signal:几乎所有c语言程序的实现过程中都要用到signal ...
- 不可或缺 Windows Native (16) - C++: 函数重载, 缺省参数, 内联函数, 函数模板
[源码下载] 不可或缺 Windows Native (16) - C++: 函数重载, 缺省参数, 内联函数, 函数模板 作者:webabcd 介绍不可或缺 Windows Native 之 C++ ...
- Swift 学习一函数&函数属性&懒加载
函数 函数相当于OC中的方法 格式: func 函数名(参数列表) -> 返回值类型 { 代码块 return 返回值} func 函数名(参数列表){ // 返回值为Void 可 ...
- 我用C#调用C编译的dll中有这样一个函数,函数大概的功能就是把数据保存到buf缓冲区中:
我用C#调用C编译的dll中有这样一个函数,函数大概的功能就是把数据保存到buf缓冲区中: C/C++ code ? 1 int retrieve(int scanno,void* buf); 在 ...
- Python第七天 函数 函数参数 函数里的变量 函数返回值 多类型传值 函数递归调用 匿名函数 内置函数
Python第七天 函数 函数参数 函数里的变量 函数返回值 多类型传值 函数递归调用 匿名函数 内置函数 目录 Pycharm使用技巧(转载) Python第一天 ...
- python基础 (初识函数&函数进阶)
函数基础部分 .什么是函数? 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率. 2.定义函数 定义:def 关键词开头,空格之后接函数名 ...
- python基础之 初识函数&函数进阶
函数基础部分 1.什么是函数? 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段.函数能提高应用的模块性,和代码的重复利用率. 2.定义函数 定义:def 关键词开头,空格之后接函数名 ...
随机推荐
- RVIZ 保存配置 and 使用配置
每次无参数启动RVIZ, 都会使用配置 -/.rviz/default.rviz 如果每次是正常退出的话,上一次的配置会被保存到文件-/.rviz/default.rviz 需要另外保存成配置文件的话 ...
- [sklearn] 实现随即梯度下降(SGD)&分类器评价参数查看
直接贴代码吧: 1 # -*- coding:UTF-8 -*- 2 from sklearn import datasets 3 from sklearn.cross_validation impo ...
- SpringCloud Config(分布式配置中心)
⒈是什么? Spring Cloud Config分为服务端和客户端两部分. 服务端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置服务器并为客户端提供获取配置信息,加密/解密信心等接口. ...
- np.nonzero()函数用法
返回数组中不为0的元素的下标. 数组中元素可为布尔.整型和浮点型,返回值为元祖 一.一维数组 1.数组元素为布尔类型 a=np.array([True,False,True,False]) b=np. ...
- Linux信号-信号集&信号屏蔽字&捕捉信号【转】
转自:https://blog.csdn.net/Lycorisradiata__/article/details/80096203 一. 阻塞信号 1. 信号的常见其他概念 实际执行信号的处理 ...
- NAND Flash底层原理,SLC MLC TLC比较【转】
转自:https://blog.csdn.net/qq_39560607/article/details/81714145 版权声明:请注明转载自Christa_RJ https://blog.csd ...
- Saltstack自动化操作记录(1)-环境部署
早期运维工作中用过稍微复杂的Puppet,下面介绍下更为简单实用的Saltstack自动化运维的使用. Saltstack知多少Saltstack是一种全新的基础设施管理方式,是一个服务器基础架构集中 ...
- struts2框架之拦截器(参考第二天学习笔记)
拦截器 1. 什么是拦截器 1). 与JavaWeb中的Filter比较相似. 2). 拦截器只能拦截Action!!! 2. Struts中定义了很多拦截器,其中defaultStack中的拦截器会 ...
- Spring MVC全局异常处理
继承HandlerExceptionResolver接口实现自己的处理方法,如: public class MyHandlerExceptionResolver implements HandlerE ...
- sqlserver 导出数据
背景 一看到这个标题,还有这个内容,感觉当初记录这个知识点真是记录的太简单了.不过通过这个知识点我还真想起了当初的一些事情.写的题外话可能更有意思,希望每篇文章我都能加个当时的题外记录.当时一直搞or ...