在 Linux 下用 C/C++ 捕获(处理)信号,通常使用 signal() 或更推荐、更可靠的 sigaction()。下面从基础到推荐做法给你说明。
信号(signal)是 Linux 中进程间异步通知机制,例如:
SIGINT (Ctrl+C)SIGTERM (终止)SIGSEGV (段错误)SIGUSR1 / SIGUSR2 (用户自定义)#include <iostream>
#include <csignal>
void handler(int sig) {
std::cout << "Received signal: " << sig << std::endl;
}
int main() {
signal(SIGINT, handler);
while (true) {}
}
✅ 简单
❌ 可移植性差,行为在不同 UNIX 上不一致
#include <iostream>
#include <csignal>
#include <unistd.h>
void handler(int sig) {
std::cout << "Caught signal: " << sig << std::endl;
}
int main() {
struct sigaction sa{};
sa.sa_handler = handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGINT, &sa, nullptr);
while (true) {
pause(); // 等待信号
}
}
void handler(int sig, siginfo_t* info, void* context) {
std::cout << "Signal: " << sig
<< ", from PID: " << info->si_pid << std::endl;
}
int main() {
struct sigaction sa{};
sa.sa_sigaction = handler;
sa.sa_flags = SA_SIGINFO;
sigaction(SIGUSR1, &sa, nullptr);
}
不能在信号处理函数中:
printfnew / deletestd::cout✅ 推荐做法:
volatile sig_atomic_t 标志volatile sig_atomic_t stop = 0;
void handler(int) {
stop = 1;
}
int main() {
signal(SIGINT, handler);
while (!stop) {
// 正常逻辑
}
}
signal(SIGINT, handler); // Ctrl+C
signal(SIGTERM, handler); // kill
signal(SIGSEGV, handler); // 段错误(谨慎)
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigprocmask(SIG_BLOCK, &set, nullptr);
✅ 生产环境用 sigaction
✅ 信号处理函数越简单越好
✅ 主循环检查标志位,不要用复杂逻辑
如果你有具体场景(守护进程 / 多线程 / 实时信号 / C++11),我可以给你更合适的示例。