深入解析Linux信号机制:从原理到实战
一、概念什么是信号信号是内核发给进程的软中断用来通知进程发生了某种事件是异步的进程不知道信号何时来二、常见信号信号名编号默认动作触发场景SIGHUP1终止终端断开SIGINT2终止ctrl cSIGQUIT3终止corectrl \SIGKILL9终止kill -9 (不可捕获)SIGSEGV11终止core段错误SIGTERM15终止kill 默认SIGSTOP19/17/23暂停CtrlZ (不可捕获)SIGCONT18/19/25继续fg/bg三、信号的三种处理方式默认处理SIG_DFL大多数信号默认是终止进程。忽略信号SIG_IGN收到信号直接丢掉不处理。SIGKILL/SIGSTOP不可忽略自定义捕捉用户函数收到信号时跳转到你写的函数执行。四、信号的生命周期产生 → 挂起(pending) → 递送(delivered) → 处理(未决) (到达进程)五、常见陷阱问题说明信号丢失同一信号多次产生未决状态下只记录一次竞态条件使用sigsuspend避免检查与等待之间的间隙中断系统调用默认会返回-1并设errnoEINTR可用SA_RESTART自动重启僵尸进程需处理 SIGCHLD 并调用 wait/waitpid不可重入信号处理函数中使用非安全函数六、代码演示#include stdio.h #include stdlib.h #include string.h #include unistd.h // 提供 sleep()、getpid() #include signal.h // 提供 signal()、信号宏定义 // 信号处理函数收到信号时自动执行 void fun(int sig) { printf(sig%d\n,sig); // 打印收到的信号编号 signal(sig,SIG_DFL); // 恢复该信号的默认处理行为 } int main() { // 注册信号处理当收到 SIGINT(2号信号CtrlC) 时执行 fun 函数 signal(SIGINT,fun); // 死循环每秒打印一次 while( 1 ) { printf(hello pid%d\n,getpid()); sleep(1); } }1.关键函数与宏signal(信号, 处理方式)作用注册信号的处理方式参数SIGINT2 号信号对应键盘Ctrl Cfun自定义信号处理函数SIG_IGN忽略信号SIG_DFL恢复系统默认行为终止进程SIGINT信号编号2触发方式键盘按下Ctrl Cgetpid()获取当前进程的 ID 号2.程序运行流程①编译运行gcc test.c -o test./test②流程讲解程序会每秒打印一行hello pid2345hello pid2345 ...第一次按 CtrlC内核给进程发送SIGINT(2)信号进程执行自定义函数fun()打印sig2关键执行signal(SIGINT, SIG_DFL)→把信号恢复成默认行为程序不会退出继续循环打印第二次按 CtrlC信号已经恢复默认 →直接终止进程程序退出回到终端