前言:
1.进程要处理信号,首先要认识信号。
2.信号一旦产生,进程可能不会立即处理,而是在合适的时候处理。
3.信号事件的产生对进程而言是异步的,就是信号不知道会什么时候产生。
4.处理信号的三个方法
5.信号无法立即处理时,就先记录下来。放在该进程的pcb中。有一个位图(32位),只有操作系统能修改这个位图
目录
1.认识信号
1-31普通信号
34-64实时信号,立即处理
kill -l命令查看全部信号
每个信号都有一个编号和一个宏定义名称,宏即编号。#define SIGINT 2(在signal.h中)
信号是数据,保存信号的方式:给一个进程发信号,当它无法处理时,就把该信号放在pcb中,位图比特位的位置代表的是信号的编号,比特位的内容代表是否收到信号,
认识信号:位图+规定
只有操作系统有资格去修改这个位图,只有操作系统才能修改pcb里面的信息。
信号的产生和信号的发送是两种概念,信号的产生有多种途径,而只有操作系统才能发信号,
2.信号的产生方式
- 对于前台进程,用户可以通过输入特殊的终端字符来给它发送信号。Ctrl-C 被驱动被操作系统拿到,操作系统也是硬件的管理者,解释成2号信号发送给目标进程。键盘产生的信号是前台信号,前台信号只能被前台进程接收到。用户可以在任何时候按下Ctrl+C,也就是信号相对于进程Ctrl的控制流是异步的。Ctrl-C产生2号信号 Ctrl-\ 产生3号信号;
- 系统异常。比如浮点异常和非法内存段访问。程序的异常,硬件异常产生信号,也被解释成信号:例如:÷0计算,计算机中只有cpu有计算功能,cpu标志位异常被操作系统拿到,向引起异常的进程发送信号,进程处理信号;
- 调用kill命令或kill函数。调用系统函数向进程发信号,例如 kill -9 pid,用以终止某个进程;kill命令是调用kill函数实现的;int kill(pid_t pid, int sig);进程给自己发信息:int raise(int sig);void abort(void);该函数使进程接到6号信号而异常终止,堆越界,assert会调用该函数。
- 系统状态变化。由软件条件产生信号,例如:管道的SIGPIPE、alarm函数产生的SIGALRM信号
Core Dump
SIGQUIT的默认动作是终止进程并且Core Dump。当一个进程异常终止时,把进程的洪湖空间内存数据全部保存到磁盘上,文件名通常是core,这叫做Core Dump。默认是不允许产生core文件的,因为core文件中可能包含⽤用户密码等敏感信息,不安全。
子进程退出时,如果父进程想要获取子进程的退出状态会定义一个输出型参数status,当调用wait函数得到子进程的退出信息后,可以根据status上的信息来判断子进程的退出情况,而status只有低16位保存子进程的退出信息,高16位并没有使用,其低16位的意义如下:
进程异常退出时,信号就记录在低八位中的低七位中,第八位表示是否Core Dump。
用ulimit -c 1024来改变core文件的大小可以打破这个限制(core文件最大为1024k),Core Dump生成的文件是core.pid
简单测试一下Core Dump。
进入gdb模式之后:core-file core.pid 接着回车即可
再测试一下由软件条件产生信号:alarm函数产生的SIGALRM信号
3.信号的处理方式
- 执行信号默认处理方案:大多是退出
- 忽略信号SIG_IGN
- 执行自定义动作SIG_DFL,提供一个信号处理函数(