信号来源与处理
有多种产生信号的方式:
- 用户在终端中按下快捷键,shell将产生信号发送至前台进程组。如Ctrl-C触发SIGINT信号,Ctrl-Z产生SIGTSTP信号,Ctrl+\产生SIGQUIT信号。
- 硬件异常产生信号,如除数为0产生SIGFPE信号,无效的内存引用产生SIGSEGV信号。
- 程序调用kill系统调用发送信号给指定进程/进程组。
- 相关软件条件发生,例如SIGURG,SIGPIPE,SIGALRM等。
进程可告知内核采取三种动作之一处理到来的信号:
-
忽略此信号。内核将不会通知进程此信号的产生,应用程序将无法获得与此信号有关的信息。
-
捕获信号。进程需要制定一个用户函数,它将在信号到来时被调用。
-
执行系统默认动作。有内核来决定忽略信号还是终止/停止进程。
SIGKILL和SIGSTOP不能被忽略或捕获。
屏蔽信号字
我们可以使用sigprocmask来为当前进程设置一个屏蔽信号字,那么此信号的传送将被阻塞,也就是说,如果内核为进程产生了一个被阻塞的信号,而且对该信号的动作是系统默认动作或捕获该信号,则内核将此信号保持为未决状态,直到该进程对此信号解除了阻塞,或者将对此信号的动作更改为忽略。
内核只有在递送该被阻塞的信号给进程时(而不是在产生此信号时)才决定对它的处理方式。所以进程在信号被递送前(即已经产生但因被阻塞而处于未决状态)仍可改变对该信号的动作。