概念:
信号是软件中断。信号提供了一种处理异步事件的方法。例如,终端用户键入中断键,会通过信号机制停止一个程序,或及早终止管道中的下一个程序。
每个信号都有一个名字,以 ’ SIG ‘ 开头。在头文件<signal.h>中,信号名都被定义为正整数常量。不存在编号为0的信号。因为kill函数对信号编号0有特殊的应用。
产生信号的条件:
- 当用户按某些终端键,引发终端产生的信号。
- 硬件异常产生信号。
- 进程调用kill函数可将任意信号发送给另一个进程或进程组。
- 用户可以用kill命令将信号发送给其他进程。
- 当检测到某种软件条件已经发生,并将其通知有关进程时也产生信号。
信号处理三动作:
- 忽略此信号
- 捕捉信号
- 执行系统默认动作
常用的信号:
信号 | 描述 | 编号 |
---|---|---|
SIGHUP | 挂起 | 1 |
SIGINT | 中断 | 2 |
SIGQUIT | 退出并转储核心 | 3 |
SIGILL | 非法指令 | 4 |
SIGTRAP | 跟踪/断点 陷阱 | 5 |
SIGABRT | 进程退出 | 6 |
SIGBUS | 总线错误,进入内存对象未定义部分 | 7 |
SIGFPE | 浮点指针异常,错误的算数 | 8 |
SIGKILL | 杀死(尽快终止) | 9 |
SIGUSR1 | 用户定义1 | 10 |
SIGSEGV | 段非法 | 11 |
SIGUSR2 | 用户定义2 | 12 |
SIGPIPE | 无读操作时写入管道 | 13 |
SIGALRM | 计时器到时 | 14 |
SIGTERM | 终止(要求终止) | 15 |
SIGSTKFLT | 协处理器堆栈错误 | 16 |
SIGCHLD | 子进程终止,停止或继续 | 17 |
SIGCONT | 继续,如果停止 | 18 |
SIGSTOP | 临时停止执行 | 19 |
SIGTSTP | 由信号终止 | 20 |
SIGTTIN | 后台进程试图从TTY 读入 (“in”) | 21 |
SIGTTOU | 后台进程试图写入TTY (“out”) | 22 |
SIGURG | I/O紧急信号 | 23 |
SIGXCPU | 超出CPU时间限制 | 24 |
SIGXFSZ | 超出文件大小限制 | 25 |
SIGVTALRM | 虚拟定时器超时 | 26 |
SIGPROF | 统计分布图用计时器到时 | 27 |
SIGWINCH | 窗口大小改变 | 28 |
SIGPOLL | Pollable event | 29 |
SIGPWR | 电力故障(System V) | 30 |
SIGSYS | 不良的系统调用 | 31 |
键盘快捷键主要有 3 种:
- Ctrl + C (相当于发送信号 2, SIGINT)
- Ctrl + Z (相当于发送信号 20, SIGTSTP)
- Ctrl + \ (相当于发送信号 3,SIGQUIT)
函数原型:
程序可用使用signal函数来处理指定的信号,主要通过忽略和恢复其默认行为来工作。signal函数的原型如下:
#include <signal.h>
void (*signal(int sig, void (*func)(int)))(int);
这是一个相当复杂的声明,可以看出signal是一个带有sig和func两个参数的函数,func是一个类型为void (*)(int)的函数指针。该函数返回一个与func相同类型的指针,指向先前指定信号处理函数的函数指针。准备捕获的信号的参数由sig给出,接收到的指定信号后要调用的函数由参数func给出。
给出一个例子来说明一下吧,源文件名为signal.c,代码如下:
#include<stdio.h>
#include <signal.h>
#include <unistd.h>
void sig_usr(int sig) {
printf("\nI got signal-%d\n", sig);
//恢复终端中断信号SIGINT的默认行为
signal(SIGINT, SIG_DFL);
}
int main() {
//改变终端中断信号SIGINT的默认行为
signal(SIGINT, sig_usr);
while(1) {
printf("Hello World!\n");
sleep(1);
}
return 0;
}
第一次按下终止命令(ctrl+c)时,进程并没有被终止,面是输出:I got signal-2,因为SIGINT的默认行为被signal函数改变了,当进程接受到信号SIGINT时,它就去调用函数sig_usr去处理,注意sig_usr函数把信号SIGINT的处理方式改变成默认的方式,所以当你再按一次ctrl+c时,进程就像之前那样被终止了。