1 信号的产生方式,信号所处状态,信号的处理方式相关概念
1.1 信号的产生方式
- 1)1. 按键产生,如:Ctrl+c、Ctrl+z、Ctrl+\。
- 2)系统调用产生,如:kill、raise、abort
- 3)软件条件产生,如:定时器alarm
- 4)硬件异常产生,如:非法访问内存(段错误)、除0(浮点数例外)、内存对齐出错(总线错误)。
- 5)命令产生,如:kill命令
1.2 信号所处状态
- 1)递达:递送并且到达进程。注意一定是到达了进程(实际是内核)。
- 2)未决:产生和递达之间的状态,更详细的描述应该是有可能发生但未发生的事情。主要由于阻塞(屏蔽)导致该状态。
- 3)非未决:不可能发生的事情。
1.3 信号的处理方式
- 1) 执行默认动作。
- 2)忽略(丢弃)
- 3)捕捉(调用户处理函数),例如你可以将程序出现段错误后发出的信号,将其捕捉后打印hello world而不让程序崩溃,当然有可能程序继续执行会发生错误。
1.4 信号相关的集合
Linux内核的进程控制块PCB是一个结构体,task_struct, 除了包含进程id,状态,工作目录,用户id,组id,文件描述符表,还包含了信号相关的信息,主要指阻塞信号集和未决信号集。
-
1)未决信号集:
-
- 信号产生,未决信号集中描述该信号的位立刻翻转为1,表信号处于未决状态。当信号被处理对应位翻转回为0。这一时刻往往非常短暂(内核产生内核处理)。
-
- 信号产生后由于某些原因(主要是阻塞)不能抵达。这类信号的集合称之为未决信号集。在屏蔽解除前,信号一直处于未决状态。
-
- 未决信号集的本质也是位图(数组存储,只能存二进制0和1),用于记录信号的状态。该信号集的信号为1,表示已产生当未被处理,一般是因为屏蔽字的阻塞导致;0表示可能处理完成或者没有产生该信号。
-
2)阻塞信号集(信号屏蔽字): 将某些信号加入集合,对他们设置屏蔽(1代表被屏蔽),当屏蔽x信号后,再收到该信号,该信号的处理将推后(解除屏蔽后才能处理)。信号屏蔽字的本质是位图,用来记录信号的屏蔽状态。一旦被屏蔽的信号,在被解除信号之前,一直处于未决状态(并非是非未决,因为它仍有可能发生)。
2 信号的处理流程
看图分析。
上图可以看到,当一个信号产生并且没有被屏蔽时的处理流程。当然也可能被屏蔽,下面我们总结一下信号被屏蔽和未屏蔽时的处理流程。
- 1)若无屏蔽,流程为上面的过程。即信号产生->未决->不阻塞->处理信号(看上面的三种方式,一般无处理执行默认)。
- 2)若有屏蔽,则流程为:信号产生->未决->阻塞。若想再被内核处理,只能等待屏蔽字改变。我记得好像需要重新发送信号才能再次执行,这里忘记了,大家可以自己试试。
- 3)需要注意的一点是,图中的第4个步骤不一定回到本进程的内核,可以是其它进程的内核。但一定是内核处理。
上面可以看到,信号的处理流程必定经过产生和未决的状态。