linux中可捕获处理的自定义信号仅限sigusr1(10)和sigusr2(12),sigkill与sigstop不可捕捉;应使用sigaction()注册处理器,shell脚本则用trap命令。

在 Linux 中捕获并处理自定义信号中断事件,核心是让进程主动注册一个处理函数,当对应信号到达时,跳转执行该函数,而不是走默认终止或忽略逻辑。关键不在于“造信号”,而在于“接住它并按需响应”。
明确可捕获的信号范围
不是所有信号都能被自定义处理。以下三类信号无法捕捉:
- SIGKILL(9号):强制终止,内核硬性执行,不可忽略也不可捕捉
- SIGSTOP(19号/17号,因架构略有差异):强制暂停,同样禁止自定义处理
- 实时信号中部分未预留的编号:建议只使用 SIGUSR1(10) 和 SIGUSR2(12) 这两个专为用户自定义用途设计的标准信号
用 sigaction 注册处理函数(推荐方式)
相比已过时的 signal(),sigaction() 更可靠、可移植、功能完整。典型用法如下:
先定义处理函数:
void my_handler(int sig) {printf("收到信号 %d,正在清理资源...\n", sig);
// 可做日志、关闭文件、释放内存等
}
再注册:
在无 root/sudo 权限的环境(云容器、VPS、隔离主机)中安装并配置 OpenClaw 浏览器工具的 headless Chrome。适用场景:...
sa.sa_handler = my_handler;
sigemptyset(&sa.sa_mask); // 初始不额外屏蔽其他信号
sa.sa_flags = 0; // 不启用 SA_RESTART 等特殊标志(按需设置)
sigaction(SIGUSR1, &sa, NULL); // 捕获 SIGUSR1
这样,只要进程收到 kill -USR1 <pid></pid>,就会执行 my_handler。
Shell 脚本中用 trap 捕获信号
对 shell 脚本,trap 是最直接的方式。例如:
echo "正在退出,清理临时文件...";
rm -f /tmp/myapp.lock;
}
trap cleanup SIGINT SIGTERM
trap 'echo "配置重载"; load_config' SIGHUP
trap cleanup EXIT
注意:trap 只在当前 shell 进程生效;EXIT 不是真实信号,而是脚本退出时触发的伪事件;SIGKILL 和 SIGSTOP 同样无法被 trap 捕获。
处理过程中的关键细节
信号不会在任意时刻立即执行处理函数。内核只在进程从内核态返回用户态前检查未决信号——比如刚完成一次 read() 系统调用、时间片到期中断返回、或处理完页错误后。此时若发现有未阻塞且已注册 handler 的信号,就临时切换到用户栈执行你的函数。函数返回后,会自动触发 sigreturn 系统调用回到内核,再恢复原程序上下文继续运行。整个过程涉及两次用户态↔内核态切换,确保安全隔离。










