信号
知识点概要
- 信号处理器程序
- 等待状态
- 信号集和信号掩码
- 信号阻塞
- 信号传递的时机与顺序
- 实时信号
一、信号处理器程序
信号处理器程序就是进程用来处理信号的函数,它们由signal()或sigaction()系统调用构建。其中,后者建立的信号处理器程序在设置信号处置方面提供了更多的控制。
二、等待状态
信号产生后,并不会立即传递到目标进程,其在产生和到达期间,信号处于等待状态。除此,信号如果在阻塞之列,亦处于等待状态。
内核将信号传递给进程需要在以下的时机进行:进程再度获得调度时(即在一个时间片开始时),系统调用完成时。
三、信号集和信号掩码
信号集:一个包含多个信号的数据结构,数据类型为sigset_t
操作信号集的一系列函数:如sigemptyset() 、sigfillset() 、sigaddset() 、sigdelset()等。
信号掩码:被置位的对应信号均被阻塞,可通过sigprocmask()函数修改进程的信号掩码。
四、信号阻塞
进程可以阻塞一些信号,当进程接受了一个该进程正在阻塞的信号,便会将该信号添加到进程的等待信号集(相当于信号掩码)中。当之后解除了对该信号的阻塞后,会随之将信号传递给此进程。
值得注意的是,由于不对普通信号进行排队处理,故如果同一信号在阻塞状态下产生多次,那么会将该信号记录在等待信号集中,但稍后只会传递一次。即如果某一标准信号已经在等待某一进程,而此时即使再次向该进程发送此信号的实例,信号也只会传递一次。
设置信号阻塞的方法:①结合信号集和信号掩码的相关系统调用;②sigaction()系统调用中可设置调用其建立的信号处理器程序时遭阻塞的信号。
五、信号传递的时机和顺序
1. 信号传递的时机
当异步产生一个信号时,即使其并未阻塞,在其产生和传递之间仍可能会存在一个(瞬时)延迟。因为内核需要等待一个恰当的时机将信号传递给进程,这个时机要满足:①进程在前度超时后,再度获得调度时;②系统调用完成时。
2. 解除对多个信号的阻塞时,信号的传递顺序
如果进程使用siprocmask()解除了多个等待信号的阻塞,那么所有这些信号会立即传递给该进程。
Linux内核按照信号编号的升序来传递信号。
六、实时信号
实时信号定义于POSIX.1b中,意在弥补对标准信号的诸多限制,故其优势如下所示:实时信号的功能可自定义,而标准信号中可供随意使用的仅有SIGUSR1和SIGUSR2;对实时信号采取队列化管理;当发送一个实时信号时,可为信号指定伴随数据。
Linux内核则定义了32个不同的实时信号,编号范围为32~63,常量SIGRTMIN、SIGRTMAX分别表示可用实时信号编号的最小值和最大值。
七、概念常识
SIGKILL和SIGSTOP信号无法被阻塞、忽略、捕获。
SIGTSTP和SIGSTOP信号:都使进程暂停运行,并且都是收到SIGCONT信号后恢复运行,惟一的区别是SIGSTOP不可被阻塞、忽略、捕获,所以它是一个必停信号。
处于停止状态的进程,当受到一个SIGCONT信号后,会恢复运行,即便它阻塞或忽略SIGCONT信号。
当进程正在执行信号处理器程序时,又接受到一个非阻塞的信号,此信号会中断进程原来正在执行的信号处理器程序。如果不想被中断,可以在sigaction()系统调用中设置“阻塞相应信号”。