Linux信号

信号
信号是一种软件中断,用来处理异步事件。信号的本质是一种进程间的通信。进程之间约定好:如果发生了某件事情T(trigger),就向目标进程(destination process)发送某特定信号X,而目标进程看到X,就意识到T事件发生了,目标进程就会执行相应的动作A(action)。

现在以配置文件改变为例,来描述整个过程。一般而言,程序会采用SIGHUP信号来通知目标进程重新加载配置文件。
Step1:目标进程首先约定,只要收到SIGHUP,就执行重新加载配置文件的动作。这个行为称为信号的安装(installation),或者信号处理函数的注册。注册完成之后,目标进程依然正常运行(由于信号是异步事件)。
Step2:当管理员改变了配置文件,就向该进程发送信号。或许在终端执行了kill-SIGHUP命令,或者调用了C的API,信号产生。
Step3:这时,Linux内核受到产生的信号,在目标进程的进程描述符里记录。Linux内核会在适当的时机,将信号递送给进程。在内核收到信号还未将信号递送给目标进程这段时间内,信号处于挂起状态,即为挂起信号(pending),也称为未决信号。
Step4:内核将信号递送给进程,进程就会暂停当前的控制流,转而去执行当前的信号处理函数。
这就是一个信号的完整生命周期。

信号的产生

信号通常源于内核,包括:
1.硬件异常:硬件检测到了错误并通知内核,由内核发送相应的信号给相关进程。
Linux信号
所以,这些进程产生之后,会立刻递送给进程。默认情况下,这四种信号都会使进程终止,并且产生core dump文件以供调试。对于这些信号,进程既不能忽略,也不能阻塞。
2.终端相关的信号:
终端定义了如下几种信号生成字符:
Ctrl+C:产生SIGINT信号;
Ctrl+:产生SIGQUIT信号;
Ctrl+Z:产生SIGTSTP信号。
SIGHUP信号和终端关系也比较密切。
3.软件事件相关的信号:
软件事件触发信号产生的情况有:
子进程退出,内核可能会向父进程发送SIGCHLD信号。
父进程退出,内核可能会给子进程发送信号。
定时器到期,给进程发送信号。

信号的默认操作

显式地忽略信号:Ignore即内核将会丢弃该信号,信号不会对目标进程产生任何影响。
终止进程:terminate很多信号默认的处理是终止进程,即将进程杀死。
生成核心转储文件并终止进程:core进程被杀死,并且产生核心转储文件。核心转储文件记录了进程死亡现场的信息。用户可以使用核心转储文件来调试,分析进程死亡的原因。
停止进程:stop 使进程暂停,将进程的状态设置成TASK_STOPPED,一旦收到恢复执行的信号,进程号可以继续执行。
恢复进程的执行:continue 和停止进程相对应,某些信号可以使进程恢复执行。