信号是类 Unix 操作系统中一种异步的进程间通知机制,内核或其他进程可以用它打断目标进程并告知某个事件发生,如终止请求、非法内存访问、子进程退出等。常见信号包括 SIGTERM、SIGKILL、SIGSEGV 等,进程可以捕获、忽略或按默认方式处理大多数信号。

| 所属领域 | 进程间通信 |
| 标准 | POSIX |
| 典型信号 | SIGTERM/SIGKILL/SIGSEGV |
| 注册接口 | signal/sigaction |
| 不可捕获信号 | SIGKILL、SIGSTOP |
信号(Signal)是类 Unix 操作系统中历史最悠久的进程间通信机制之一,本质上是一种异步事件通知:内核在特定事件发生时向进程投递一个编号,进程收到后中断当前流程,转去执行预设的处理逻辑。它可以看作软件层面的中断。
信号最早出现在贝尔实验室的早期 Unix 中,如今由 POSIX 标准规范。每个信号有唯一的编号和名字,例如 SIGTERM(15)请求进程终止、SIGKILL(9)强制杀死进程、SIGSEGV(11)表示段错误、SIGCHLD 表示子进程状态变化、SIGINT 对应终端上的 Ctrl+C。用户可以通过 kill 命令向指定进程发送信号,程序内部则使用 kill、raise 等系统调用发送,用 signal 或功能更完整的 sigaction 注册处理函数。
信号广泛用于服务进程的生命周期管理:管理员用 SIGTERM 优雅停止服务、用 SIGHUP 通知守护进程重新加载配置(nginx 即采用此约定);shell 用 SIGINT、SIGTSTP 实现前台任务的中断与挂起;父进程通过 SIGCHLD 得知子进程退出以便回收。编写信号处理函数时必须只调用异步信号安全的函数,否则可能引发难以复现的竞态问题,这也是现代程序常改用 signalfd 或自管道技巧把信号转为普通事件处理的原因。
问:kill 命令只能杀进程吗?答:不是。kill 的本义是发送信号,默认发送 SIGTERM。它同样可以发送 SIGHUP、SIGUSR1 等信号用于重载配置或自定义用途,杀进程只是最常见的用法。
问:SIGTERM 和 SIGKILL 有什么区别?答:SIGTERM 可以被进程捕获,给程序保存数据、释放资源的机会,是优雅退出的首选;SIGKILL 无法被捕获或忽略,内核直接终止进程,应作为最后手段。
问:为什么信号处理函数里不能随便调用 printf?答:信号可能在任意时刻打断主流程,若主流程正持有 printf 内部的锁,处理函数再次进入就会死锁。POSIX 规定处理函数中只能调用异步信号安全函数。

| 所属领域 | 进程间通信 |
| 标准 | POSIX |
| 典型信号 | SIGTERM/SIGKILL/SIGSEGV |
| 注册接口 | signal/sigaction |
| 不可捕获信号 | SIGKILL、SIGSTOP |
登录 后参与讨论
暂无讨论,来发表第一条评论吧