这一章解决的核心问题:进程如何“被打扰”与“自保”
在 Linux 系统编程中,信号(Signal)是进程间通信最轻量、也最底层的手段。很多同学容易把信号当成简单的“杀死进程”工具,但本章的核心在于厘清:当进程正在执行关键代码(如内存分配、文件 IO)时,收到一个中断信号,程序该如何优雅地响应?这是从“能跑代码”到“写出健壮服务”的关键跨越。
本章主要解决三个能力缺口:一是理解信号的生命周期,包括发送、投递、阻塞与处理;二是掌握 signal 函数的陷阱,特别是在老式 BSD 信号处理中,处理函数执行后信号掩码可能重置的风险;三是理解系统调用被信号中断后的恢复机制,即为什么 sleep 被中断后需要重新计算剩余时间。如果不理解这些,你在编写守护进程或服务器时,会因为一个 Ctrl+C 或网络异常导致程序状态错乱甚至崩溃。
学习路径建议:先懂机制,再谈封装
这门课的内容密度很高,建议按以下顺序攻克:
- 基础认知(第1-4节):先搞清楚 Linux 下常用信号有哪些(如 SIGKILL, SIGTERM, SIGSEGV),以及 kill、pkill 命令的区别。重点看 core 文件的产生条件,这是排查段错误的必要前置知识。
- 核心函数深挖(第5-7节):signal 函数是本章难点。务必重视第 6、7 节,讲解 signal 返回值的细节以及需要强调的“可移植性陷阱”。很多老旧教材只讲用法不讲坑,这里会明确告诉你为什么在现代编程中更推荐 sigaction,以及 signal 在什么情况下会失效。
- 并发与同步(第8-15节):这是进阶部分。第8、9节讲子进程继承信号处理的规则,第10节扩展 kill/raise/alarm 等发送函数。第11、12节关于“休眠被中断”的讨论是面试高频点,必须看懂 EINTR 错误的处理逻辑。最后两节讲信号屏蔽字(sigprocmask),理解如何原子地保护临界区。
跳过前面的基础直接看信号屏蔽,会因为缺乏对信号投递流程的感性认识而感到抽象。务必先看第13节“信号发生、接收、处理的详细过程”,这能帮你建立全局视图。
学完能做什么?资料如何配合
完成本章学习后,你应该能够独立回答以下问题:为什么子进程会继承父进程的信号处理函数?当 SIGINT 信号打断 sleep 时,程序该如何继续休眠?如何临时屏蔽某些信号以保护关键代码段不被中断?
配套的练习资料(视频对应的源码或习题)应遵循“先破坏,再修复”的策略。建议先手动 kill 掉运行中的测试程序,观察其行为;然后尝试用 signal 注册处理函数,故意制造“信号中断系统调用”的场景,验证程序是否会报错或停滞。不要只看不练,信号的处理流程非常依赖直觉,只有通过打断程序执行,观察 stack trace 和返回值,才能真正内化 EINTR 和信号屏蔽的概念。本章节不涉及复杂的网络模型,但它是后续学习多进程服务器、异步 IO 的基石,务必扎实掌握。
课程目录
1 什么是信号,学习信号有什么意义 (12:56) 2 Linnux下常用信号有哪些 (20:53) 3 kill与pkill命令 (15:04) 4 信号的发送与接收、core文件 (10:42) 5 signal函数 (17:01) 6 signal函数的返回值 (21:02) 7 需要强调的地方 (10:49) 8 子进程对父进程信号的继承 1 (16:17) 9 子进程对父进程信号的继承 2 (15:39) 10 kill raise alarm等函数 (21:33) 11 休眠函数被信号中断 1 (16:57) 12 休眠函数被信号中断 2 (07:23) 13 信号发生、接收、处理的详细过程 (16:44) 14 修改信号屏蔽字 1 (14:16) 15 修改信号屏蔽字 2 (09:32)





