Linux系统编程--信号及信号处理(一)

时间:2021-04-05 14:42:37

Linux信号介绍

一、信号解释

信号是一种软件中断,它提供了一种处理异步事件的方法,也是进程间唯一的异步通信方式。在linux系统中,根据POSIX标准扩展以后的信号机制,不仅可以用来通知某进程发生了什么事件,还可以给进程传递数据。

二、信号的来源

  • 硬件方式

    1.当用户在终端上按下某些键时,将产生信号。
    2.硬件异常产生信号:除数为0,无效的存储访问等。这些事件通常由硬件(如CPU)检测到,并将其通知给Linux操作系统内核,然后内核生成相应的信号,并把信号发送给该时间发生时正在运行的程序。

  • 软件方式

    1.用户在终端下调kill命令向进程发送任意信号。
    2.进程调用kill或sigqueue函数发送信号。
    3.当检测到某种软件条件已经具备时发出信号,如由alarm或settimer设置的定时器超时时将生成SIGALRM信号。

三、信号的种类

Linux系统编程--信号及信号处理(一)

1、可靠信号与不可靠信号

SIGHUP(1号)至SIGSYS(31号)之间的信号都是继承自UNIX系统,是不可靠信号。Linux系统根据POSIX.4标准定义了SIGRTMIN(33号)与SIGRTMAX(64号)之间的信号,他们都是可靠信号,也称为实时信号。

在linux系统中,信号的可靠性是指信号是否会丢失,或者说该信号是否支持排队。当导致产生信号的事件发生时,内核就产生一个信号。信号产生后,内核通常会在进程表中设置某种形式的标志。当内核设置了这个标志,我们就说内核向一个进程递送了一个信号。信号产生和递送之间的时间间隔,称为信号未决。

进程可以调用sigpending将信号设置为阻塞,如果为进程产生了一个阻塞的信号,而对该信号的动作时捕捉该信号(即不忽略信号),则内核将为该进程的此信号保持为未决状态,直到该进程对此信号解除阻塞或将对此信号的响应更改为忽略。如果在进程解除对某个信号的阻塞之前,这种信号发生了多次,那么如果信号被递送多次(即信号在未决信号队列里面排队),则称之为可靠信号;只被递送一次的信号称为不可靠信号。

2、信号的优先级

信号实质上是软中断,中断有优先级,信号也有优先级。如果一个进程有多个未决信号,则对于同一个未决的实时信号,内核将按照发送的顺序来递送信号,如果存在多个未决的实时信号,则值(或者说编号)越小的越先被递送。如果既存在不可靠信号,又存在可靠信号(实时信号),虽然POSIX对这一情况没有明确规定,但linux系统和大多数遵循POSIX标准的操作系统一样,将优先递送不可靠信号。

3、进程对信号的响应

当信号发生时,用户可以要求进程以下列3种方式之一对信号做出响应。

  • 捕捉信号。对于要捕捉的信号,可以为其指定信号处理函数,信号发生时该函数自动被调用,在该函数内部实现对该信号的处理。
  • 忽略信号。大多数信号都可以使用这种方式进行处理,但是SIGKILL和SIGSTOP这两个信号不能被忽略,同时这两个信号也不能被捕获和阻塞。此外,如果忽略某些由硬件异常产生的信号(如非法存储访问或除以0),则进程的行为是不可预测的。
  • 按照系统默认方式处理。大部分信号的默认操作时终止进程,且所有的实时信号的默认动作都是终止进程。