Unix环境高级编程 读书笔记 第十章 信号

信号概念

信号是软件中断,信号提供了一种处理异步事件的方法。
每个信号都有一个名字,以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系统信号概括为:
在这里插入图片描述

很多条件可以产生信号:

  1. 用户按下某些终端键,引起终端产生信号;
  2. 硬件异常被检测到,通知内核,内核为该条件发生时正在运行的进程产生信号;
  3. 进程调用kill函数将任意信号发送给另一个进程或者进程组;
  4. 用户使用kill命令(是kill命令,不是函数)将信号发送给其他进程;
  5. 当检测到某种软件条件产生,将其通知有关进程时,产生信号。

当信号产生时,进程对信号的处理或者与信号有关的动作可以包括:

  1. 忽略此信号。有2种信号不能被忽略,即SIGKILL和SIGSTOP信号。这2个信号不能被忽略的原因是:他们向内核和root提供了是进程终止或者停止运行的可靠方法;
  2. 捕捉信号。通知内核在某种信号发生时,调用一个用户函数。不能捕捉SIGKILL和SIGSTOP信号。
  3. 执行系统默认动作。大多数信号的系统默认动作是终止该进程。

信号的具体含义如下:
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指定为接收到此信号后要调用的函数的地址,则在信号发生时,调用该函数。

猜你喜欢

转载自blog.csdn.net/jiangzhangha/article/details/86001866