信号
异步通知
信号 是 CoddyKit 上的免费 C Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C Academy 课程共包含 4 节课。
什么是信号
信号是发送给进程的异步通知,用于告知进程某个事件已经发生,例如用户按下 Ctrl-C 或子进程退出。信号是一种轻量级 IPC 形式。
常见信号
您经常会遇到以下几种信号:
SIGINT中断(Ctrl-C)SIGTERM礼貌的终止请求SIGKILL强制终止(无法捕获)SIGCHLD子进程状态发生变化SIGSEGV无效的内存访问
默认处理方式
每个信号都有一个默认操作:终止、终止并生成核心转储、忽略、停止或继续。您可以通过处理函数覆盖其中的大多数默认操作。
安装处理函数
设置处理函数的现代、可移植方式是使用 sigaction。处理函数是一个接收信号编号的函数。
#include <signal.h>
#include <stdio.h>
void on_signal(int sig) {
/* note: printf is not async-signal-safe; for demo only */
write(1, "caught\n", 7);
}
int install(void) {
struct sigaction sa = {0};
sa.sa_handler = on_signal;
return sigaction(SIGINT, &sa, NULL);
}为什么不使用 signal()
旧的 signal() 函数在不同系统上的行为并不一致(处理函数会被重置,且无法控制 SA_RESTART)。请优先使用定义明确且可移植的 sigaction。
异步信号安全函数
处理函数可能在代码执行的任意时刻打断程序,因此只能调用 异步信号安全的函数,例如 write。在处理函数中调用 printf 或 malloc 可能导致死锁或数据损坏。
使用 volatile 标志
一种安全的模式是:处理函数设置一个 volatile sig_atomic_t 标志,主循环对其进行检查。这样可以让处理函数保持简短且安全。
#include <signal.h>
volatile sig_atomic_t stop = 0;
void handler(int sig) {
stop = 1; /* only set a flag */
}
/* main loop: while (!stop) { do_work(); } */发送信号
使用 kill(pid, sig) 向另一个进程发送信号,或使用 raise(sig) 向自身发送信号。尽管名称中有 kill,它可以发送任意信号,而不只是致命信号。
#include <signal.h>
int notify(int pid) {
return kill(pid, SIGTERM); /* ask process to terminate */
}阻塞信号
为了保护关键区段,请使用 sigprocmask 和信号集暂时阻塞信号。被阻塞的信号会保持为待处理状态,并在解除阻塞后送达。
#include <signal.h>
void block_int(void) {
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigprocmask(SIG_BLOCK, &set, NULL);
}使用 SIGCHLD 回收子进程
子进程退出时,内核会发送 SIGCHLD。调用 waitpid 的处理函数会回收子进程,防止产生一直留在进程表中的僵尸进程。
#include <signal.h>
#include <sys/wait.h>
void reap(int sig) {
while (waitpid(-1, NULL, WNOHANG) > 0)
; /* reap all finished children */
}无法捕获的信号
有两个信号是绝对的:SIGKILL 始终终止进程,SIGSTOP 始终停止进程。它们无法被捕获、阻塞或忽略,为系统提供了控制进程的可靠方式。
快速检查
测试您对信号的理解。
回顾
您已经学习了如何使用信号进行异步通知。
- 使用
sigaction而不是旧的signal安装处理函数 - 处理函数必须是异步信号安全的;最好只设置一个标志
- 使用
kill/raise发送信号;使用sigprocmask阻塞信号 - 收到 SIGCHLD 时回收子进程;SIGKILL 和 SIGSTOP 无法被捕获
用 AI 导师学习 C — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 39
- 课程
- 144
常见问题解答
「信号」课时是免费的吗?
是的 — 「信号」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C Academy 课程的其余内容,请升级到 CoddyKit PRO。 C Academy 课程共包含 4 节课。
「信号」这节课中我会学到什么?
异步通知 你通过在浏览器中直接运行的动手代码来练习 C Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 C Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 C Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「信号」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 C Academy 课中编写并运行代码吗?
能。每节 C Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。