信号处理
基本概念:
1、中断:
当程序接收信息后中止当前执行的程序,转而执行其他任务,等其他任务执行完成后再 返回,这种执行模式叫中断,分为硬件中断和软件中断
2、信号
是一种软件中断,由操作系统发出,程序接收到会执行相应操作
3、常见的信号
SIGINT(2) Ctrl+c 终止
SIGQUIT(3) Ctrl+\ 终止+core
SIGFPE(8) 除0 终止+core
SIGKILL(9) 终止信号 终止
SIGSEGV(11) 非法访问内存 终止+core
注意:kill -l 查看Linux所有信号
4、不可靠信号和可靠信号
建立在早期的信号处理机制上的信号(1-31)是不可靠信号
不支持排队,有丢失可能,同一个信号如果产生多次,进程可能只接收到一次
建立在新信号处理机制上的信号(34-64)是可靠信号
支持排队,不会丢失
5、信号来源
硬件异常:除0、无效的内存访问、未定义的指令、总线错误
软件异常:通过一些命令、函数产生的信号
6、信号处理方式
1、忽略
2、终止进程
3、终止进程并产生core文件
4、捕获信号并处理(当信号发送前,先向内核注册一个函数,当信号发生时让系统自动执行该函数)
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
功能:向内核注册一个信号处理函数
signum:要注册的信号编号
handler:函数指针
还可以用以下参数:
SIG_IGN 忽略
SIG_DFL 按照默认方式
返回值:之前的信号处理方式
注意:
有些系统通过signal注册的函数只能执行一次,如果想要持续有效,可以在信号处理函数最后在注册一次
子进程会继承父进程的信号处理方式,如果通过exce系列函数来创建子进程,子进程会 恢复默认的信号处理方式
如果我们捕获并处理段错误或者算术异常信号可能产生死循环,因为信号处理完后会返回到信号产生的代码处进行处理,就可能导致死循环,正确的段错误和算术异常的处理方式应该是先备份数据并结束进程
void sigint(int num)
{
printf("你瞎摁啥?\n");