在Linux环境下使用C++进行信号处理,通常涉及以下几个步骤:
包含头文件:
#include <csignal>
定义信号处理函数:
信号处理函数必须符合特定的签名,通常是void handler(int signum);
。
void signalHandler(int signum) {
std::cout << "Interrupt signal (" << signum << ") received.\n";
// 清理并关闭资源
// 终止程序
exit(signum);
}
注册信号处理函数:
使用signal
或sigaction
函数来注册信号处理函数。sigaction
提供了更高级的控制和更多的功能。
#include <signal.h>
int main() {
// 注册信号 SIGINT 和它的处理函数
signal(SIGINT, signalHandler);
// 或者使用 sigaction
struct sigaction sa;
sa.sa_handler = signalHandler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGINT, &sa, NULL);
// 程序的主循环
while (true) {
// 做一些事情
}
return 0;
}
触发信号:
你可以通过键盘(通常是Ctrl+C)或者使用kill
命令来发送信号给进程。
注意事项:
printf
、malloc
等,因为它们可能不是异步信号安全的。使用sigaction
的优势:
sigaction
提供了比signal
更多的控制,例如可以设置信号掩码,指定信号处理函数在执行时是否会被阻塞等。
示例代码:
下面是一个使用sigaction
的完整示例,它展示了如何捕获SIGINT
信号(通常由Ctrl+C产生)并优雅地终止程序。
#include <iostream>
#include <csignal>
#include <cstdlib>
volatile sig_atomic_t stop;
void signalHandler(int signum) {
stop = 1;
}
int main() {
struct sigaction sa;
sa.sa_handler = signalHandler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGINT, &sa, NULL);
std::cout << "Program is running. Press Ctrl+C to stop it.\n";
while (!stop) {
// 主循环
}
std::cout << "Program stopped.\n";
return 0;
}
在使用信号处理时,要特别注意信号的随机性和并发性,以及信号处理函数的安全性。正确地处理信号对于编写健壮的服务器和长时间运行的应用程序至关重要。