1. 信号入门
1.1 生活角度的信号
1. 你在网上买了很多件商品,再等待不同商品快递的到来。但即便快递没有到来,你也知道快递来临时,你该怎么处理快递。也就是你能“识别快递”
2. 当快递员到了你楼下,你也收到快递到来的通知,但是你正在打游戏,需5min之后才能去取快递。那么在在这5min之内,你并没有下去去取快递,但是你是知道有快递到来了。也就是取快递的行为并不是一定要立即执行,可以理解成“在合适的时候去取”。
3. 在收到通知,再到你拿到快递期间,是有一个时间窗口的,在这段时间,你并没有拿到快递,但是你知道有一个快递已经来了。本质上是你“记住了有一个快递要去取”
4. 当你时间合适,顺利拿到快递之后,就要开始处理快递了。而处理快递一般方式有三种:1. 执行默认动作(幸福的打开快递,使用商品)2. 执行自定义动作(快递是零食,你要送给你你的女朋友)3. 忽略快递(快递拿上来之后,扔掉床头,继续开一把游戏)
5. 快递到来的整个过程,对你来讲是异步的,你不能准确断定快递员什么时候给你打电话
总结:
生活例子 --- 提炼基本结论:
1. 信号在生活中, 随时可以产生 --- 信号的产生和我是 "异步的"
2. 你能认识这个信号
3. 我们知道信号产生了, 信号该怎么处理 --- 你能识别并处理这个信号
4. 我们可能正在做着更重要的事情 (打游戏), 把到来的信号暂不处理 (但是我们记得这个事, 具体什么时候处理, 等我们合适的时候)
我, 我们 => 进程
1.2 技术应用角度的信号
用户输入命令,在Shell下启动一个前台进程。
用户按下Ctrl-C ,这个键盘输入产生一个硬件中断,被OS获取,解释成信号,发送给目标前台进程
前台进程因为收到信号,进而引起进程退出
比如我们写下这个代码:
#include <stdio.h>
#include <unistd.h>
int main()
{
while(1)
{
printf("I am a process, I am waiting signal!\n");
sleep(1);
}
return 0;
}
将代码编译后运行:
按下ctrl + c之后
其实进程就是你, 操作系统就是快递员, 信号就是快递!
1.3 注意
1. Ctrl-C 产生的信号只能发给前台进程。一个命令后面加个&可以放到后台运行,这样Shell不必等待进程结束就可以接受新的命令,启动新的进程。
2. Shell可以同时运行一个前台进程和任意多个后台进程,只有前台进程才能接到像 Ctrl-C 这种控制键产生的信号。
3. 前台进程在运行过程中用户随时可能按下 Ctrl-C 而产生一个信号,也就是说该进程的用户空间代码执行到任何地方都有可能收到 SIGINT 信号而终止,所以信号相对于进程的控制流程来说是异步(Asynchronous)的。
1.4 信号概念
经过上面的铺垫, 我们可以得出结论 : 信号是进程之间事件异步通知的一种方式,属于软中断!
1.5 用kill -l命令查看系统定义的信号列表
使用下面命令查看系统定义的信号列表:
kill -l
1. 每个信号都有一个编号和一个宏定义名称, 这些宏定义名称可以在signal.h中找到, 例如其中有定义#define SIGINT 2
2. 编号34以上的是实时信号, 这里只讨论34以下的信号, 不讨论实时信号, 这些信号各自在什么条件下产生, 默认的处理动作是什么, 在signal(7) 中都有详细说明 :
3. 真正发送信号的其实只有操作系统一个人可以
使用命令 : man 7 signal
man 7 signal
1.6 信号处理常见方式概览
可选的处理动作有以下三种 :
1. 忽略此信号
2. 执行该信号的默认处理动作
3. 提供一个信号处理函数, 要求内核在处理该信号时切换到用户态执行这个处理函数, 这种方式称为捕捉(Catch)一个信号
2. 产生信号
系统产生信号有5种情况 :
2.1 通过kill命令, 向指定进程发送指定信号
我们可以写一个死循环代码, 然后通过kill杀死进程:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
while(1)
{
printf("I am a process pid : %d, I am waiting signal!\n", getpid());
sleep(1);
}
return 0;
}
使用kill命令, 给进程2号信号 --- SIGINT, 相当于在键盘输入了ctrl + c
2.2 键盘可以产生信号
我们比较常用的键盘信号有 : ctrl +c ctrl + \ 分别对应信号 : SIGINT SIGQUIT
还是上面一样的代码, 我们使用键盘命令终止:
知识补充:
什么是core dumped?
首先解释什么是Core Dump。当一个进程要异常终止时,可以选择把进程的用户空间内存数据全部保存到磁盘上,文件名通常是core,这叫做Core Dump。进程异常终止通常是因为有Bug,比如非法内存访问导致段错误,事后可以用调试器检查core文件以查清错误原因,这叫做Post-mortem Debug(事后调试)。一个进程允许产生多大的core文件取决于进程