引言
信号是软件中断。很多比较重要的应用程序都需要处理信号。信号提供了一种处理异步事件的方法,例如:终端用户键入中断键,会通过信号机制停止一个程序,或及早终止管道的下一个程序。
信号概念
-
信号是什么:UNIX 进程间的一种异步通讯机制。
-
信号的作用:提醒目标进程某事件的发生,并中断了目标进程正常的控制流程。
-
进程对信号的处理:目标进程可以执行信号的默认处理函数,或者执行进程自定义的信号处理程序。
每个信号都有一个名字, 这些名字都以三个字符 SIG 开头。 例如,SIGABRT是夭折信号, 当进程调用 abort 函数时产生这种信号。SIGALRM 是闹钟信号,当由 alarm 函数设置的计时器超时后产生此信号。在 UNIX 系统中,这些信号都定义在头文件 <signal.h> 中,并且都是以一个正整数来表示(信号编号)。通过在 shell 中运行命令 kill -l 可以查看当前系统所执行的所有信号。
信号的来源主要有:
-
硬件产生,例如除零操作、非法访问内存等;
-
软件产生,例如通过kill/raise/alarm/setitmer/sigqueue函数产生。
UNIX 系统规定了内核可以对信号执行以下三种处理行为,
-
忽略此信号。有两个信号 SIGKILL 和 SIGSTOP 不可忽略,这两个信号提供给超级用户终止或停止进程的可靠方法。
-
执行系统默认动作。大多数信号的默认动作是终止进程。
-
捕获信号,执行用户自定义的处理函数。
下面列出了所有信号的名字,说明哪些系统支持此信号以及对于这些信号的系统默认动作。
UNIX系统信号
信号的捕获
UNIX系统信号机制最简单的接口是 signal 函数。
#include<signal.h>
sighandler_t signal(int signum, sighandler_t handler);
功能:信号处理注册函数
参数:
signum:信号名,介于1~31之间的信号编号
handler:它的值为常量SIG_ING、常量SIG_DFL或当接到此信号后要调用的地址。
返回值:
成功返回以前的信号处理配置;出错返回SIG_ERR
注意:在某些UNIX系统上,signal注册的函数只执行一次,执行完后就恢复成默认处理方式。如果想长期使用该函数处理信号,可以在函数结束前再注册一次。
以上的signal函数原型或许太复杂了,可以写的简单一些
typedef void Sigfunc(int);
//然后将signal函数原型写成
Sigfunc *signal(int,Sigfunc *);
函数kill和raise
kill 函数将信号发送给进程或进程组。
raise函数则允许进程向自身发送信号。
int kill(pid_t pid, int sig);
参数:
pid:进程的id
pid>0 | 向进程号为pid的进程发送信号 |
pid=0 | 向同组一进程组的进程发送信 |