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,检测哪 ...
随机推荐
- ubuntu远程桌面连接命令rdesktop连接windows远程桌面详解
sudo apt-get install rdesktoprdesktop 124.42.120.174:1433 呵呵,连接成功了. -f 全屏-a 16位色默认端口是3389(linux 22 s ...
- salesforce lightning零基础学习(三) 表达式的!(绑定表达式)与 #(非绑定表达式)
在salesforce的classic中,我们使用{!expresion}在前台页面展示信息,在lightning中,上一篇我们也提及了,如果展示attribute的值,可以使用{!v.expresi ...
- JAVA不可变类(immutable)机制与String的不可变性
一.不可变类简介 不可变类:所谓的不可变类是指这个类的实例一旦创建完成后,就不能改变其成员变量值.如JDK内部自带的很多不可变类:Interger.Long和String等. 可变类:相对于不可变类, ...
- C++笔记十二:C++对C的扩展——struct关键字类型增强
C语言的struct定义了一组变量的集合,C编译器并不认为这是一种新的类型. C++中的struct是一个新类型的定义声明. struct Student { char name[100]; int ...
- ACM Robot Motion
机器人已被编程为按照其指令中的路径进行操作.机器人要移动的下一个方向的指令放在网格中.可能的指令是 N north (up the page) S south (down the page) E ...
- ACM Max Factor
To improve the organization of his farm, Farmer John labels each of his N (1 <= N <= 5,000) co ...
- DrawerLayout案例
布局文件: <?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget ...
- 手动创建第一个OC程序
手动创建第一个OC程序 创建一个文件夹,文件夹内创建一个a.m的OC源文件,并编辑 之前说过,OC是完全兼容C语言的,那么我们先写个下面的程序尝试一下 #include<stdio.h> ...
- Leetcode解题-链表(2.2.6)RotateList
1 题目:Rotate List Given a list, rotate the list to the right by k places, where k is non-negative. Fo ...
- FFmpeg源代码简单分析:avcodec_close()
===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...