信号的概念及类型
信号是Linux系统中用于进程之间通信或操作的一种机制,信号可以在任何时候发送给某一进程,而无须知道该进程的状态。如果该进程并未处于执行状态,则该信号就由内核保存起来,直到该进程恢复执行并传递给他为止。如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞被取消时才被传递给进程。
收到信号的进程对各种信号有不同的处理方法。处理方法可以分为三类:
- 第一种是类似中断的处理程序,对于需要处理的信号,进程可以指定处理函数,由该函数来处理。
- 第二种方法是,忽略某个信号,对该信号不做任何处理,就象未发生过一样。
- 第三种方法是,对该信号的处理保留系统的默认值,这种缺省操作,对大部分的信号的缺省操作是使得进程终止。进程通过系统调用signal来指定进程对某个信号的处理行为。
在linux下我们可以使用 kill -l 命令查看当前系统支持的信号,需要注意的是不同的系统支持的信号是不一样的:
在上面的信号中,我们常见或用到的是:
信号编号 | 信号名 | 信号说明 | 默认动作 |
---|---|---|---|
2 | SIGINT | Ctrl+c按键终止程序运行的信号 | 程序终止 |
4 | SIGILL | 非法的指令 | 程序终止 |
7 | SIGBUS | 运行非本CPU相关编译器编译的程序 | 程序终止 |
9 | SIGKILL | 强制杀死程序信号,任何程序都不可以捕捉该信号 | 程序终止,不可被捕捉 |
10 | SIGUSR1 | 用户自定义信号1 | 程序终止 |
11 | SIGSEGV | 段错误系统给程序发送的信号 | 程序终止 |
12 | SIGUSR2 | 用户自定义信号2 | 程序终止 |
13 | SIGPIPE | 管道破裂信号 | 程序终止 |
14 | SIGALRM | alarm()系统调用发送的信号 | 程序终止 |
15 | SIGTERM | kill命令默认发送的信号,默认动作是终止信号 | 程序终止 |
17 | SIGCHLD | 子进程退出信号 | 忽略该信号 |
信号的安装
linux下主要有两个函数实现信号的安装:signal()、sigaction()。
1、signal()
#include <signal.h> //头文件
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
函数说明:注册一个信号捕捉函数
参数说明:① 第一个参数signum指定信号的值。②第二个参数handler制定针对前面函数的处理,可忽略该信号(参数设为SIG_IGN),可以采用系统默认方式处理信号(参数设为SIG_DFL),也可以自己实现处理方式(参数指定一个函数地址),即当指定信号到底时,就会跳转到handler指定的函数执行。
返回值:signal()调用成功时,返回最后一次为安装信号signum而调用signal()时的handler值,失败返回SIG_ERR。
2、sigaction()
#include <signal.h>
int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact);
函数说明:函数可对发来的信号做排队处理(通常在Linux用其来注册一个信号的捕捉函数)
参数说明:①第一个参数signum为要操作的信号,可以为SIGKILL及SIGSTOP外的任何一个特定有效的信号(这两个信号定义自己的处理函数,导致安装错误)。②第二个参数act为指向sigaction结构体的一个指针,在结构体中指定了对信号新的处理方式,当为NULL时,进程会按缺省的方式对信号处理。③第三个参数oldact参数输出先前信号的处理方式,也可指为NULL。若第二个参数和第三个参数都为NULL则该函数用来检查信号的有效性。
struct sigaction结构体如下:
struct sigaction {
void (*sa_handler)(int);
void