要说Linux中的信号,不得不先提一下中断这个概念。中断是系统中对于异步事件的响应,也就是说某个进程可以在代码执行的过程中被打断了,它先去执行一段异常处理程序。中断可以分为硬件中断,也就是外部中断,它是由外部设备通过硬件请求的方式产生的中断。而软件中断,也就是内部中断,它是由CPU运行程序的一些错误或者执行内部程序调用的时候引起的一种中断。
在CPU的层面去看中断,是这样的一个步骤: ①中断源发出中断信号 ②CPU判断是屏蔽该中断以及现场保护③CPU查询中断向量表,找到相应服务程序的入口地址,然后执行中断处理程序④中断处理完之后,恢复现场,继续执行原来的任务
信号和中断是很类似的,但是信号是*nix操作系统响应某些状况而产生的事件,进程在接受到信号之后会采取相应的行动,信号可以理解为是在软件层次上的一种模拟。信号与中断的相似点主要有:①都使用了相同的异步通信方式,②当检测到信号或者中断请求时,都会暂停当前的程序会执行相应的处理程序,③在执行后返回到原来的断点处继续执行④我们对信号和中断都可以进行屏蔽。
信号与中断的区别主要有:①中断有优先级,但是信号是没有优先级的。②信号处理是在用户态下运行的,而中断处理是运行在核心态下的。③中断相应是及时的,因为它是由CPU直接处理的,而信号响应则通常会有较大的时间延迟。
Linux的信号机制是继承的Unix系统中的,早期Unix的信号机制不够完善,可能导致进程对信号做出错误的反应以及信号可能会丢失。Linux下对信号机制进行了改进,Linux下信号的主要问题就是信号可能会丢失。这些可能出现问题的信号就是不可靠信号。
为了实现可靠信号,同时也为了向前兼容,后来又增加了一些信号,这些信号都是可靠信号,这些信号支持排队、不会丢失。早期Unix只定义了31种信号,而Linux3.x则定义了64种信号,编号从1到64。前面的31种信号都有预定值,每个信号的用途以及含义都是确定的,它们也都有相对应的缺省动作。后面的32种信号表示实时信号,它们也就是所谓的可靠信号,它保证了发送的多个实时信号都被接受,实时信号是POSIX的一部分。值得注意的是非实时信号都不支持排队,都是不可靠信号,而实时信号都支持排队,都是可靠信号。
信号被发出之后,当信号被执行的时候的处理动作就称为信号递达,而信号从产生到递达之间的这段时间,被称为信号未决。进程可以阻塞某个信号,被阻塞的信号从产生就一直处于未决状态,直到进程解除了对该信号的阻塞,该信号才有可能会执行递达的动作。
值得注意的是,阻塞不同于忽略。信号被阻塞时就不会递达,而忽略则是在递达之后的一种处理方式。