问题
按下 Ctrl + C 后,命令行中的前台进程会被终止。为什么???
什么是信号?
信号是一种 "软件中断",用来处理异步事件
- 内核发送信号到某个进程,通知进程事件的发送
- 事件可能来自硬件,可能来自用户输入,可能来自除零错误
信号是一种类型的进程间通信方式 (一个进程向另一个进程发送信号)
- A 进程发生事件 T,向 B 进程发送信号,B 进程执行动作响应事件
- 进程可以对接收到的不同信号进行不同响应动作 (信号 => 处理)
信号的分类
硬件异常
- 内核检测到硬件错误,发送相应信号给相关进程
终端信号
- 在终端输入 "特殊字符" 等价于向前台进程组发送相应信号
软件信号
- 在软件层面 (进程代码中) 触发的信号 (发送给自身或其他进程)
硬件异常信号
终端相关信号
SIGINT ( Ctrl + C )
- 程序终止信号,用于通知前台进程组终止进程
SIGQUIT ( Ctrl + \ )
- 与 SIGINT 类似,进程收到该信号退出时可产生 coredump 文件
SIGTSTP ( Ctrl + Z )
- 停止进程的运行,进程收到该信号后可以选择处理或忽略
软件相关信号
子进程退出:父进程收到 SIGCHLD 信号
父进程退出:子进程可能收到信号 (什么信号?)
定时器到期:alarm(),ualarm(),timer_create(),...
主动发信号:kill(),raise(),...
内核与信号
信号的默认处理
知识加油站:System V vs BSD
System V
- 也被称为 AT&T System V,是 Unix 操作系统众多版本中的一支
BSD
- 加州大学伯克利分校开创,Unix 衍生系统,代表由此派生出的各种套件集合
自定义信号处理
#include <sys/types.h>
#include <signal.h>
typedef void(*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
sighandler_t sysv_signal(int signum, sighandler_t handler);
sighandler_t bsd_signal(int signum, sighandler_t handler);
信号处理示例
自定义信号发送
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig); // pid > 0, pid == 0, pid < -1
int raise(int sig); // 信号处理完毕才返回
信号发送示例
思考
三种自定义信号处理函数有什么区别???