信号概念
信号是软件中断,信号提供了一种处理异步事件的方法。
每个信号都有一个名字,以SIG字符开头,信号名被定义为正整数常量,对于Linux系统,其信号名被定义在<bit/signum.h>中。
/* Fake signal functions. */
#define SIG_ERR ((__sighandler_t) -1) /* Error return. */
#define SIG_DFL ((__sighandler_t) 0) /* Default action. */
#define SIG_IGN ((__sighandler_t) 1) /* Ignore signal. */
#ifdef __USE_UNIX98
# define SIG_HOLD ((__sighandler_t) 2) /* Add signal to hold mask. */
#endif
/* Signals. */
#define SIGHUP 1 /* Hangup (POSIX). */
#define SIGINT 2 /* Interrupt (ANSI). */
#define SIGQUIT 3 /* Quit (POSIX). */
#define SIGILL 4 /* Illegal instruction (ANSI). */
#define SIGTRAP 5 /* Trace trap (POSIX). */
#define SIGABRT 6 /* Abort (ANSI). */
#define SIGIOT 6 /* IOT trap (4.2 BSD). */
#define SIGBUS 7 /* BUS error (4.2 BSD). */
#define SIGFPE 8 /* Floating-point exception (ANSI). */
#define SIGKILL 9 /* Kill, unblockable (POSIX). */
#define SIGUSR1 10 /* User-defined signal 1 (POSIX). */
#define SIGSEGV 11 /* Segmentation violation (ANSI). */
#define SIGUSR2 12 /* User-defined signal 2 (POSIX). */
#define SIGPIPE 13 /* Broken pipe (POSIX). */
#define SIGALRM 14 /* Alarm clock (POSIX). */
#define SIGTERM 15 /* Termination (ANSI). */
#define SIGSTKFLT 16 /* Stack fault. */
#define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */
#define SIGCHLD 17 /* Child status has changed (POSIX). */
#define SIGCONT 18 /* Continue (POSIX). */
#define SIGSTOP 19 /* Stop, unblockable (POSIX). */
#define SIGTSTP 20 /* Keyboard stop (POSIX). */
#define SIGTTIN 21 /* Background read from tty (POSIX). */
#define SIGTTOU 22 /* Background write to tty (POSIX). */
#define SIGURG 23 /* Urgent condition on socket (4.2 BSD). */
#define SIGXCPU 24 /* CPU limit exceeded (4.2 BSD). */
#define SIGXFSZ 25 /* File size limit exceeded (4.2 BSD). */
#define SIGVTALRM 26 /* Virtual alarm clock (4.2 BSD). */
#define SIGPROF 27 /* Profiling alarm clock (4.2 BSD). */
#define SIGWINCH 28 /* Window size change (4.3 BSD, Sun). */
#define SIGPOLL SIGIO /* Pollable event occurred (System V). */
#define SIGIO 29 /* I/O now possible (4.2 BSD). */
#define SIGPWR 30 /* Power failure restart (System V). */
#define SIGSYS 31 /* Bad system call. */
#define SIGUNUSED 31
#define _NSIG 65 /* Biggest signal number + 1
(including real-time signals). */
#define SIGRTMIN (__libc_current_sigrtmin ())
#define SIGRTMAX (__libc_current_sigrtmax ())
UNIX系统信号概括为:
很多条件可以产生信号:
- 用户按下某些终端键,引起终端产生信号;
- 硬件异常被检测到,通知内核,内核为该条件发生时正在运行的进程产生信号;
- 进程调用kill函数将任意信号发送给另一个进程或者进程组;
- 用户使用kill命令(是kill命令,不是函数)将信号发送给其他进程;
- 当检测到某种软件条件产生,将其通知有关进程时,产生信号。
当信号产生时,进程对信号的处理或者与信号有关的动作可以包括:
- 忽略此信号。有2种信号不能被忽略,即SIGKILL和SIGSTOP信号。这2个信号不能被忽略的原因是:他们向内核和root提供了是进程终止或者停止运行的可靠方法;
- 捕捉信号。通知内核在某种信号发生时,调用一个用户函数。不能捕捉SIGKILL和SIGSTOP信号。
- 执行系统默认动作。大多数信号的系统默认动作是终止该进程。
信号的具体含义如下:
SIGABRT:调用函数abort时产生该信号,进程异常终止;
SIGALRM:用alarm函数设置的定时器超时时,产生该信号;
SIGBUS:指示一个实现定义的硬件故障;
SIGCHLD:在一个子进程终止或者停止时,该信号被送给其父进程。
SIGCONT:此信号发送给需要继续运行,但是当前处于停止状态的进程。
SIGEMT:指示一个实现定义的硬件故障;
SIGFPE:表示一个算术运算异常,比如除以0,浮点溢出等;
SIGHUP:当终端接口检测到一个连接断开,则将此信号发送给与该终端相关的控制进程(会话首进程);
SIGILL:表示进程已执行一条非法的硬件指令;
SIGINT:用户输入中断键(ctrl + c),终端驱动程序产生此信号,并将其发送至前台进程组的所有进程;
SIGIO:指示一个异步IO事件;
SIGIOT:指示一个实现定义的硬件故障;
SIGKILL:向系统管理员提供一种可以杀死任一进程的可靠方法;
SIGPIPE:如果在管道的读进程已经终止时写管道,则产生此信号;
SIGQUIT:用户输入退出键(ctrl + \)时,中断驱动程序产生此信号,发送给前台进程组中的所有进程。此信号不仅终止前台进程组,而且产生一个core文件;
SIGSEGV:指示进程进行了一次无效的内存引用(segmentation violation);
SIGSTOP:一个作业控制信号,停止一个进程;
SIGSYS:指示一个无效的系统调用;
SIGTERM:由kill命令发送的系统默认终止信号,该信号由应用程序捕获;
SIGTRAP:指示一个实现定义的硬件故障;
SIGTSTP:用户键入挂起键(ctrl + z),终端驱动程序产生此信号,该信号发送至前台进程组中的所有进程;
SIGTTIN:当一个后台进程组进程试图读控制终端时,终端驱动程序产生此信号;
SIGTTOU:当一个后台进程组进程试图写控制终端时,终端驱动程序产生此信号;
SIGURG:此信号通知进程已经发生一个紧急情况;
SIGUSR1:由用户定义的信号;
SIGUSR2:由用户定义的信号;
函数signal
UNIX系统信号机制最简单的接口是signal函数:
#include <signal.h>
void (*signal(int signo, void (*func)(int)))(int);
/*若成功,返回以前的信号处理函数指针,若出错,返回SIG_ERR*/
此函数的原型比较复杂,使用typedef可使得其简单些:
typedef void Sigfunc(int);
Sigfunc *signal(int, Sigfunc *);
函数的入参signo是信号名,func表示信号处理程序的地址,可以取值为SIG_IGN、SIG_DFL、或者当接收到此信号后要调用的函数的地址。
func指定为SIG_IGN表示将忽略此信号。
func指定为SIG_DFL表示接收到此信号后的动作是系统默认动作。
func指定为接收到此信号后要调用的函数的地址,则在信号发生时,调用该函数。