Linux信号实践(1) --Linux信号编程概述
中断
中断是系统对于异步事件的响应, 进程执行代码的过程中可以随时被打断,然后去执行异常处理程序;
计算机系统的中断场景:中断源发出中断信号 -> CPU判断中断是否屏蔽屏蔽以及保护现场 -> CPU(查询中断向量表, 找到中断服务程序的入口地址)执行中断处理程序 ->(处理完中断之后) ->恢复现场,继续执行原来的任务
中断分类
硬件中断(外部中断)
外部中断是指由外部设备通过硬件请求的方式产生的中断,也称为硬件中断
软件中断(内部中断)
内部中断是由CPU运行程序错误或执行内部程序调用引起的一种中断,也称为软件中断(如:执行除0操作, 由用户空间陷入内核空间等)。
信号
信号是UNIX/Linux系统响应某些状况而产生的事件,进程在接收到信号时会采取相应的行动。信号一般是因为某些错误条件而产生的,比如内存段冲突、浮点处理器错误或者非法指令等;信号是在软件层次上对中断的一种模拟,所以通常把它称为是软中断;
信号与中断的相似点:
(1)采用了相同的异步通信方式;
(2)当检测出有信号或中断请求时,都暂停正在执行的程序而转去执行相应的处理程序;
(3)都在处理完毕后返回到原来的断点;
(4)对信号或中断都可进行屏蔽。
信号与中断的区别:
(1)中断有优先级,而信号没有优先级,所有的信号都是平等的;
(2)信号处理程序是在用户态下运行的,而中断处理程序是在核心态下运行;
(3)中断响应是及时的,而信号响应通常都有较大的时间延迟。
常用信号
|
信号名称 |
描述 |
|
SIGABRT(6) |
进程停止运行 |
|
SIGALRM |
警告钟 |
|
SIGFPE |
算述运算例外(如除0) |
|
SIGHUP |
系统挂断 |
|
SIGILL |
非法指令 |
|
SIGINT(2) |
终端中断 |
|
SIGKILL |
停止进程(此信号不能被忽略或捕获) |
|
SIGPIPE |
向没有读者的管道写入数据 |
|
SIGSEGV |
无效内存段访问 |
|
SIGQUIT |
终端退出 |
|
SIGTERM |
终止 |
|
SIGUSR1 |
用户定义信号1 |
|
SIGUSR2 |
用户定义信号2 |
|
SIGCHLD |
子进程已经停止或退出 |
|
SIGCONT |
如果被停止则继续执行 |
|
SIGSTOP |
停止执行 |
|
SIGTSTP |
终端停止信号 |
|
SIGTOUT |
后台进程请求进行写操作 |
|
SIGTTIN |
后台进程请求进行读操作 |
进程对信号的响应
忽略信号
不采取任何操作、有两个信号不能被忽略:SIGKILL和SIGSTOP。
[为什么进程不能忽略SIGKILL/SIGSTOP信号。(如果应用程序可以忽略这2个信号,系统管理无法杀死、暂停进程,无法对系统进行管理。)]
捕获并处理信号
内核中断正在执行的代码,转去执行先前注册过的处理程序。
执行默认操作
默认操作通常是终止进程,这取决于被发送的信号。
信号的默认操作:通过 man 7 signal 查看
信号安装-signal
typedef void (*__sighandler_t) (int); #define SIG_ERR ((__sighandler_t) -1) #define SIG_DFL ((__sighandler_t) 0) #define SIG_IGN ((__sighandler_t) 1) __sighandler_t signal(int signum, __sighandler_t handler);
参数
signal是一个带signum和handler两个参数的函数,准备捕捉或屏蔽的信号由参数signum给出,接收到指定信号时将要调用的函数由handler给出
handler这个函数必须有一个int类型的参数(即接收到的信号代码),它本身的类型是void, handler也可以是下面两个特殊值:
SIG_IGN 屏蔽该信号
SIG_DFL 恢复默认行为
//示例1
void handler(int sigNum)
{
cout << "recv a signal = " << sigNum << endl;
}
int main(int argc, char *argv[])
{
signal(SIGINT, handler);
while (true)
sleep(1);
}
RETURN VALUE
signal() returns the previous value of the signal handler, or SIG_ERR on error.
In the event of an error, errno is set to indicate the cause.
int main(int argc, char *argv[])
{
sighandler_t oldHandler = signal(SIGINT, handler);
if (oldHandler == SIG_ERR)
err_exit("signal error");
while (getchar() != '\n')
sleep(1);
// 等价于 signal(SIGINT, SIG_DFL)
if (signal(SIGINT, oldHandler) == SIG_ERR)
err_exit("signal error");
while (true)
sleep(1);
}
//实例: 捕获所有信号, 并打印信号的信息
int main()
{
for (int i = 1; i < NSIG; ++i)
{
if (signal(i, sigHandler) == SIG_ERR)
{
cerr << "signal " << i << ": " << strsignal(i) << " set error";
cerr << ", errno desc: " << strerror(errno) << endl;
}
}
while (true)
pause();
}
void sigHandler(int signo)
{
cout << "catch a signal, signo = " << signo << ", desc: " << strsignal(signo) << endl;
}
Linux信号实践(1) --Linux信号编程概述的更多相关文章
- Linux信号实践(4) --可靠信号
Sigaction #include <signal.h> int sigaction(int signum, const struct sigaction *act, struct si ...
- Linux进程实践(1) --Linux进程编程概述
进程 VS. 程序 什么是程序? 程序是完成特定任务的一系列指令集合. 什么是进程? [1]从用户的角度来看:进程是程序的一次执行过程 [2]从操作系统的核心来看:进程是操作系统分配的内存.CPU时间 ...
- Linux信号实践(2) --信号分类
信号分类 不可靠信号 Linux信号机制基本上是从UNIX系统中继承过来的.早期UNIX系统中的信号机制比较简单和原始,后来在实践中暴露出一些问题,它的主要问题是: 1.进程每次处理信号后,就将对信号 ...
- Linux驱动实践:中断处理函数如何【发送信号】给应用层?
作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++.嵌入式.Linux. 关注下方公众号,回复[书籍],获取 Linux.嵌入式领域经典书籍:回复[PDF],获取所有原创文章( PDF 格式). ...
- Linux信号实践(3) --信号内核表示
信号在内核中的表示 执行信号的处理动作称为信号递达(Delivery),信号从产生到递达之间的状态,称为信号未决(Pending).进程可以选择阻塞(Block)某个信号.被阻塞的信号产生时将保持在未 ...
- 与信号相关的linux系统编程API
1. kill(pid_t pid, int sig); //给指定的进程发送sig信号 raise(int sig); //给当前进程发送sig信号2. 处理指定的信号 typedef v ...
- linux 进程学习笔记-进程信号sigal
信号(或软中断)是在软件层次上对中断的一个模拟,其运行在“用户空间”,一个进程对另外一个或几个进程通过发送信号来实现异步通信.当接收进程接收到信号后,其可以注册一下处理函数来说对这些信号进行处理(也可 ...
- xenomai内核解析之信号signal(一)---Linux信号机制
版权声明:本文为本文为博主原创文章,转载请注明出处.如有错误,欢迎指正.博客地址:https://www.cnblogs.com/wsg1100/ 目录 1. Linux信号 1.1注册信号处理函数 ...
- Linux下shell脚本中信号捕获和函数练习脚本之ping一个网段
该脚本主要的目的是练习在Linux bash脚本中捕获信号,顺便练习一下函数的使用,还有就是终止一个正在运行的程序后,该程序打开的文件的后续处理问题等等!脚本功能: ping一个网段内的IP,检测哪 ...
随机推荐
- 分享一个二维码图片识别控制台程序Demo
怎么用NuGet和配置log4net就不介绍了,直接上代码(QRDecodeDemo.zip). (Visual Studio 2015 下的项目,用的.NET Framework 4.5.2) 吐槽 ...
- Android艺术开发探索第四章——View的工作原理(下)
Android艺术开发探索第四章--View的工作原理(下) 我们上篇BB了这么多,这篇就多多少少要来点实战了,上篇主席叫我多点自己的理解,那我就多点真诚,少点套路了,老司机,开车吧! 我们这一篇就扯 ...
- hexo常用命令
Hexo 约有二十个命令,但普通用户经常使用的只有下列几个: hexo s hexo s是hexo server的缩写,命令效果一致:启动本地服务器,用于预览主题.默认地址: http://local ...
- Java异常处理机制难点解惑-用代码说话
是否需要看这篇文章? 下面的例子中,如果正常执行返回值多少? 如果出现了ArithmeticException返回值多少? 如果出现非ArithmeticException(如NullPointerE ...
- Android必知必会-发布开源 Android 项目注意事项
如果移动端访问不佳,请使用 –> Github版 1. 合理配置 .gitignore 文件 配置 .gitignore 可以排除一些非必要文件和保护保密信息,下面是在项目根目录下 .gitig ...
- 1026. Table Tennis (30)
题目如下: A table tennis club has N tables available to the public. The tables are numbered from 1 to N. ...
- Windows平台下的多线程编程
线程是进程的一条执行路径,它包含独立的堆栈和CPU寄存器状态,每个线程共享所有的进程资源,包括打开的文件.信号标识及动态分配的内存等.一个进程内的所有线程使用同一个地址空间,而这些线程的执行由系统调度 ...
- 如何使用excel画甘特图
甘特图小伙伴们都非常的熟悉,首先小编简单的向各位小伙伴介绍一下什么是甘特图,甘特图内在思想简单,即以图示的方式通过活动列表和时间刻度形象地表示出任何特定项目的活动顺序与持续时间.基本是一条线条图,横轴 ...
- Objc中处理数组越界的一种办法
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) Objc的数组如果在访问时索引非法,则会抛出NSRangeEx ...
- Ruby开发入门
开发环境搭建 首先安装Ruby SDK,我安装的版本是2.0.之后安装IDE,这里用的是Jetbrain的RubyMine 5.4.3,注意是否支持对应版本的Ruby SDK. 一段神奇的注册码... ...