【linux】信号的理论概述和实操
目录
理论篇
信号概述
信号的分类
信号机制
理解硬件中断
异步
信号对应的三种动作
信号产生的条件
终端按键
系统调用
软件条件
硬件异常
除0错误
野指针
OS对于错误的态度
信号在进程中的内核数据结构
信号的处理
CPU的内核态和用户态概述
进程处理信号的时机
编辑
在递达时该信号被屏蔽
实操篇
sigset_t
信号集操作函数
sigprocmask
参数
返回值
sigpending
参数
返回值
sigaction
参数
返回值
struct sigaction 结构
闹钟
参数
返回值
注意事项
signal
个人主页东洛的克莱斯韦克
理论篇
信号概述
在Linux系统中,信号是一种软件中断,用于通知进程发生了某个事件
信号是由操作系统发送给进程的,用于通知进程某个条件已经发生或者需要执行某个动作,进程处理信号的默认动作可用如下命令查看
man 7 signal
信号提供了一种进程间通信的机制,虽然它主要是用来通知异常或中断情况,但也可以被用来实现进程间的同步或控制
信号的分类
信号分为普通信号 和 实时信号
用如下指令查看信号
kill -l
在Linux系统中1号信号到31号信号为普通信号,34号到64号信号为实时信号。每一种信号都有自己的宏定义。
实时信号一般用于特定的系统中,如嵌入式系统,能够在特定的硬件上运行并对外部事件做出迅速响应的系统。一个很贴近生活的例子是车载系统,如果用户层踩了刹车,车载系统即使再忙也要马上做出响应。实时信号会打破进程占用CPU资源的公平性。
而普通信号不会破坏进程占用CPU的资源的公平性,本文重点探讨普通信号。
信号机制
信号的机制属于一种软件中断,它模拟的是硬件中断
理解硬件中断
硬件中断是指当硬件设备(如网卡、硬盘、键盘等)有数据或事件需要处理时,会自动向CPU发送一个中断请求(IRQ),CPU在收到中断请求后,会暂停当前正在执行的任务,转而执行处理该中断请求的程序,这一过程称为硬件中断处理。
也就是说OS不会耗费资源去检查外设的数据情况,而是检测CPU是否收到中断请求。
以键盘为例,OS不可能知道用户什么时候敲键盘,OS也不会检测键盘是否有数据,只有用户敲键盘了,键盘会给CPU发送中断请求,OS检查到CPU的中断请求,才会把数据从键盘文件刷到内核缓冲区。
硬件中断是硬件行为,信号是在软件层模拟硬件中断。操作系统给进程发送相应的信号,进程收到信号完成某些任务。
异步
与硬件中断类似,进程不知道操作系统什么时候给自己发送信号。由于信号可以在进程执行的任何时间点到来,且进程通常不会预先知道何时会收到信号,因此信号的接收是异步的。
信号对应的三种动作
默认动作 忽略 自定义
默认动作:每一个信号对应一个动作。就比如红绿灯的 红灯 ,绿灯, 黄灯 分别对应停止, 前进, 等一等。
信号编号 | 信号名称 | 默认动作 | 备注 |
---|---|---|---|
1 | SIGHUP | 终止进程 | 当用户退出shell时,由该shell启动的所有进程将接收此信号 |
2 | SIGINT | 终止进程 | 相当于Ctrl+C,通常用于终止前台进程 |
3 | SIGQUIT | 终止进程并生成core文件 | 相当于Ctrl+,除了终止进程外,还会生成core文件用于调试 |
4 | SIGILL | 终止进程并生成core文件 | 非法指令,例如执行了未知或不支持的指令 |
5 | SIGTRAP | 终止进程并生成core文件 | 跟踪/断点陷阱,通常与调试器相关 |
6 | SIGABRT | 终止进程并生成core文件 | 调用abort()函数产生的信号,用于异常终止进程 |
7 | SIGBUS | 终止进程并生成core文件 | 总线错误,非法访问内存地址(如对齐错误) |
8 | SIGFPE | 终止进程并生成core文件 | 浮点异常,如除以0、溢出等 |
9 | SIGKILL | 终止进程 | 不能被捕捉、阻塞或忽略,无条件终止进程 |
10 | SIGUSR1 | 终止进程 | 用户自定义信号1,程序员可以在程序中定义并使用该信号 |
11 | SIGSEGV | 终止进程并生成core文件 | 无效的内存引用,如解引用空指针 |
12 | SIGUSR2 | 终止进程 | 用户自定义信号2,程序员可以在程序中定义并使用该信号 |
13 | SIGPIPE | 终止进程 | 写入没有读端的管道,常见于socket编程中 |
14 | SIGALRM | 终止进程 | 由alarm()函数设置的定时器超时产生 |
15 | SIGTERM | 终止进程 | 请求程序终止,与SIGKILL不同,SIGTERM可以被捕捉、阻塞或忽略 |
16-17 | SIGSTKFLT | 终止进程 | 协处理器栈错误(已废弃,在某些系统上可能不存在) |
SIGCHLD | 忽略 | 子进程停止或终止时,通知父进程,但父进程通常选择忽略此信号 | |
18 | SIGCONT | 继续执行被停止的进程 | 使一个停止的进程继续执行(如果它被停止的话) |
19 | SIGSTOP | 停止进程 | 不能被捕捉、阻塞或忽略,无条件停止进程 |
20 | SIGTSTP | 停止进程 | 相当于Ctrl+Z,用于暂停前台进程 |
21-22 | SIGTTIN | 停止进程 | 后台进程尝试从控制终端读取时产生(如后台进程尝试读取输入) |
SIGTTOU | 停止进程 | 后台进程尝试向控制终端写入时产生(如后台进程尝试输出) | |
23-31 | SIGURG, ... | 依赖于具体实现 | 这些信号的默认动作可能因系统而异,且一些信号可能不在所有系统上都有定义 |
忽略:进程屏蔽了该信号
自定义:进程捕捉了该信号
9号信号和19号信号不能被捕捉也不能被屏蔽。
9号信号是用来杀进程的且一定能杀掉,用来处理有问题的进程,恶意攻击系统的进程等等