信号是软中断,它提供了一种处理异步事件的方法。
首先,每个信号都有一个名字。这些名字都以三个字符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/。