目录
1. 信号的概念
信号是一个软件中断,相当于是一个口头的约束,对你的限制力比较低,举个例子来说就是当你买的快递到了需要你去取的时候,而你正在打游戏,你并没有下去去取快递,但是你是知道有快递到来了。也就是取快递的行为并不是一定要立即执行,可以理解成“在合适的时候去取。在这个过程中,你获得了一个取快递的信号,但是你并没有选择立即执行,而是选择了在合适的时候去取,这就是软件中断。
2. 信号的种类
-
目前Linux的信号数量为62个,分为两种类型:
① 非实时信号(非可靠信号),对应信号量为
1~31,它的特点是有可能信号会发送丢失
② 实时信号(可靠信号),对应信号量为34~64,它的特点是信号不会发送丢失 -
kill -l:可以罗列出具体的信号值。
-
man 7 singal:罗列所有的信号的具体信息。信号的具体信息:
信号的动作:

如果某一个信号的处理动作是core,那么它默认是需要完成终止进程+产生coredump文件。产生coredump文件依赖于ulimit -a中对应的core file size,并将其设置为unlimited。
3. 信号的产生
3.1 硬件产生
ctrl + c:使当前运行的进程中断,产生一个值为2号的信号量,是一个SIGINT。ctrl + z:使当前运行的进程停止,产生一个值为20号的信号量,是一个SIGTSTP。ctrl + |:使当前运行的进程退出,产生一个值为3号的信号量,是一个SIGQUIT。
3.2 软件产生
- kill 命令
kill [PID]:终止一个进程。
kill -[num] [PID]:给进程号为PID的进程发送一个信号值为num的信号。 - kill 函数(包含在
#include<signal.h>中,是一个系统调用函数)int kill(pid_t pid, int sig);
功能是:给pid进程发送sig的信号。 - raise函数(包含在
#include<signal.h>中,是一个库函数)int raise(int sig)
功能:谁调用给谁发送signal信号。
4. 信号的注册
- 一个进程接收到一个信号,这个过程就被称之为信号的注册。
- 信号的注册和信号的注销并不是一个过程,是两个独立的过程。
- 信号的注册分为两种情况:可靠信号的注册和非可靠信号的注册。
在说可靠信号的注册和非可靠信号注册之前,我们先来看看信号在操作系统内核中到底是怎样存储的。
4.1 信号注册在内核中的存储表示
① 首先我们查看源码中的
struct task_struct结构体(PCB)中关于信号的处理程序即signal handlers,我们本节就看其中的一个变量struct sigpending pending。
② 然后我们转到该结构体的内部定义对其进行查看
发现有一个sigset_t类型的变量,这个sigset_t类型应该是被typedef出来的。③ 我们使用
grep在内核源码中对sigset_t进行搜索,发现其包含在signal.h文件中。
④ 在signal.h头文件中对sigset_t进行查看
说明sigset_t类型是一个结构体,它包含了一个无符号长整型的数组。
至此,我们可以清楚的知道信号注册时在内核中到底是如何存储的。
总结一下就是:

本文详细介绍了Linux信号的概念,包括非实时和实时信号的种类,以及信号的硬件和软件产生方式。接着,讨论了信号在内核中的存储表示,非可靠和可靠信号的注册与注销过程。此外,还阐述了信号的默认、忽略和自定义处理方式,重点对比了signal函数和sigaction函数的区别。最后,分析了信号在内核层面的处理流程。




最低0.47元/天 解锁文章





