信号之信号概念

来源:互联网 时间:1970-01-01

信号是软中断,它提供了一种处理异步事件的方法。

首先,每个信号都有一个名字。这些名字都以三个字符SIG开头

在头文件<signal.h>中,这些信号都被定义为正整数(信号编号)。

实际上,实现将各信号定义在另一个头文件中,但是该头文件又包括在<signal.h>中。通常,若应用程序和内核两者都需使用同一定义,那么就将有关信息放置在内核头文件中,然后用户级头文件再包括该内核头文件

不存在编号为0的信号。(kill函数对信号编号0有特殊的应用。POSIX.1将此种信号编号值称为空信号。)

产生信号的条件:

  • 当用户按某些终端键时,引发终端产生的信号。
  • 硬件异常产生信号。
  • 进程调用kill(2)函数可将信号发送给另一个进程或进程组。(自然,对此有所限制:接收信号进程和发送信号进程的所有者必须相同,或者发送信号进程的所有者必须是超级用户。)
  • 用户可用kill(1)命令将信号发送给其他进程。
  • 当检测到某种软件条件已经发生,并应将其通知有关进程时也产生信号。(这里指的不是硬件产生的条件,而是软件条件。)

信号是异步事件的经典实例。产生信号的事件对进程而言是随机出现的。进程不能简单地测试一个变量(例如errno)来判别是否出现了一个信号,而是必须告诉内核“在此信号出现时,请执行下列操作”。

可以要求内核在某个信号出现时按照下列三种方式之一进行处理,我们称之为信号的处理或者与信号相关的动作

(1)忽略此信号。大多数信号都可使用这种方法进行处理,但是有两种信号决不能被忽略:SIGKILL和SIGSTOP。这两种信号不能被忽略的原因是:它们向超级用户提供了使进程终止或停止的可靠方法。另外,如果忽略某些由硬件异常产生的信号(例如除以0),则进程的运行行为是未定义的。

(2)捕捉信号。为了做到这一点,要通知内核在某种信号发生时调用一个用户函数。在用户函数中,可执行用户希望对这种事件进行的处理。注意,不能捕捉SIGKILL和SIGSTOP信号

(3)执行系统默认动作。注意,针对大多数信号的系统默认动作是终止进程。

表10-1列出了所有信号的名字,说明了哪些系统支持此信号以及针对这些信号的系统默认动作。在“默认动作”列中,“终止+core”表示在进程当前工作目录的core文件中复制该进程的存储映像。大多数UNIX调试程序都使用core文件以检查进程终止时的状态

                                                                              表10-1 UNIX系统信号

UNIX系统信号:

Signal                 Description

SIGABRT              调用abort函数产生此信号,进程异常终止

SIGALRM              用alarm函数设置的计时器超时或setitimer函数设置的间隔时间超时

SIGBUS                某种特定的硬件异常,通常由内存访问引起

SIGCANCEL          由Solaris 线程库内部使用,它不供一般使用

SIGCHLD              进程终止或停止的时候,SIGCHLD会发送给它的父进程。缺省情况下该信号会被忽略。如果父进程希望被告知其子进程的这种状态改变,则应捕捉此信号,信号捕捉函数中通常要调用一种wait函数以取得子进程ID和其终止状态。

SIGCONT             此作业控制信号被发送给需要继续运行,但当前处于停止状态的进程。如果接收到此信号的进程处于停止状态,则系统默认动作是使该进程继续运行,否则默认动作是忽略此信号。

SIGEMT                和实现相关的硬件异常

SIGFPE                此信号表示一个算术运算异常,如被0除,浮点溢出,等等

SIGFREEZE          Solaris专用,它用于通知进程在冻结系统状态之前需要采取特定动作。

SIGHUP               如果终端接口检测到一个连接断开,则将此信号发送给与该终端相关的控制进程(会话首进程)。注意,接收到此信号的会话首进程可能在后台。如果会话首进程终止,则也产生此信号。在这种情况下,此信号被发送给前台进程组中的每一个进程。

SIGILL                 此信号指示进程已执行一条非法硬件指令。

SIGINFO              BSD signal。当用户按状态键(一般采用Ctrl+T)时,终端驱动程序产生此信号并送至前台进程组中的每一个进程。此信号通常导致在终端上显示前台进程组中个进程的状态信息。

SIGINT                由Interrupt Key产生,通常是CTRL+C或者DELETE。发送给所有ForeGround Group的进程

SIGIO                  异步IO事件

SIGIOT                实现相关的硬件异常,一般对应SIGABRT

SIGKILL               无法捕捉和忽略。它向系统管理员提供了一种可以杀死任一进程的可靠方法。

SIGLWP              由Solaris Thread Libray内部使用,并不作一般使用

SIGPIPE              如果在写管道时读进程已终止,则产生此信号。当类型为SOCK_STREAM的套接字已不再连接时,进程写到该套接字也产生此信号。

SIGPOLL             当在一个可轮询设备上发生一特定事件时产生此信号。

SIGPROF             当setitimer(2)函数设置的梗概统计间隔计时器(profiling interval timer)已到期时产生此信号。

SIGPWR              和系统相关。和UPS相关。

SIGQUIT              输入Quit Key的时候(CTRL+\)发送给所有Foreground Group的进程

SIGSEGV             非法内存访问(SEGV,segmentation violation,段违例)

SIGSTKFLT          Linux专用,数学协处理器的栈异常

SIGSTOP             停止一个进程。无法捕捉和忽略。

SIGSYS               无效的系统调用

SIGTERM             这是由kill(1)命令发送的系统默认终止信号。

SIGTHAW           Solaris专用,从Suspend恢复时候发送

SIGTRAP             实现相关的硬件异常。一般是调试异常

SIGTSTP             Suspend Key,一般是Ctrl+Z。发送给所有Foreground Group的进程

SIGTTIN             当Background Group的进程尝试读取Terminal的时候发送

SIGTTOU            当Background Group的进程尝试写Terminal的时候发送

SIGURG              此信号通知进程已发生一个紧急情况。当out-of-band data接收的时候可能发送

SIGUSR1            用户自定义signal 1,可用于应用程序

SIGUSR2            用户自定义signal 2,可用于应用程序

SIGVTALRM        setitimer函数设置的Virtual Interval Timer超时的时候

SIGWAITING      Solaris Thread Library内部实现专用

SIGWINCH         当Terminal的窗口大小改变的时候,发送给Foreground Group的所有进程

SIGXCPU           如果进程超过了其软CPU时间限制,则产生此信号。

SIGXFSZ            如果进程超过了其软文件长度限制,则产生此信号。

SIGXRES           Solaris专用,进程超过资源限制的时候发送

 

本篇博文内容摘自《UNIX环境高级编程》(第二版),仅作个人学习记录所用。关于本书可参考:http://www.apuebook.com/


相关阅读:
Top