Appearance
C++ 信号处理
信号是操作系统向进程发送的通知,用于处理异步事件,如中断、错误等。C++ 提供了<csignal>头文件来处理信号。
1. 信号的基本概念
信号是操作系统向进程发送的异步通知,用于处理各种事件,如用户中断、段错误、非法内存访问等。
1.1 常见的信号
| 信号 | 描述 |
|---|---|
SIGINT | 中断信号(Ctrl+C) |
SIGTERM | 终止信号 |
SIGABRT | 异常终止信号 |
SIGFPE | 浮点异常 |
SIGILL | 非法指令 |
SIGSEGV | 段错误 |
SIGALRM | 定时器信号 |
2. signal 函数
signal函数用于设置信号处理函数。
2.1 基本语法
cpp
#include <csignal>
void (*signal(int sig, void (*func)(int)))(int);示例
cpp
#include <iostream>
#include <csignal>
#include <unistd.h>
void signal_handler(int signal) {
std::cout << "接收到信号: " << signal << std::endl;
}
int main() {
signal(SIGINT, signal_handler);
std::cout << "按 Ctrl+C 发送 SIGINT 信号" << std::endl;
while (true) {
sleep(1);
}
return 0;
}3. 信号处理函数
3.1 处理 SIGINT 信号
cpp
#include <iostream>
#include <csignal>
#include <unistd.h>
void sigint_handler(int signal) {
std::cout << "\n接收到 SIGINT 信号,程序即将退出" << std::endl;
exit(0);
}
int main() {
signal(SIGINT, sigint_handler);
std::cout << "按 Ctrl+C 发送 SIGINT 信号" << std::endl;
while (true) {
sleep(1);
}
return 0;
}3.2 处理 SIGTERM 信号
cpp
#include <iostream>
#include <csignal>
#include <unistd.h>
void sigterm_handler(int signal) {
std::cout << "接收到 SIGTERM 信号,程序即将退出" << std::endl;
exit(0);
}
int main() {
signal(SIGTERM, sigterm_handler);
std::cout << "使用 kill 命令发送 SIGTERM 信号" << std::endl;
std::cout << "程序 PID: " << getpid() << std::endl;
while (true) {
sleep(1);
}
return 0;
}3.3 处理 SIGALRM 信号
cpp
#include <iostream>
#include <csignal>
#include <unistd.h>
void sigalrm_handler(int signal) {
std::cout << "定时器到期" << std::endl;
}
int main() {
signal(SIGALRM, sigalrm_handler);
std::cout << "设置 5 秒定时器" << std::endl;
alarm(5);
while (true) {
sleep(1);
}
return 0;
}4. raise 函数
raise函数用于向当前进程发送信号。
cpp
#include <iostream>
#include <csignal>
void signal_handler(int signal) {
std::cout << "接收到信号: " << signal << std::endl;
}
int main() {
signal(SIGINT, signal_handler);
std::cout << "发送 SIGINT 信号" << std::endl;
raise(SIGINT);
return 0;
}5. 信号处理和异常
5.1 处理 SIGFPE 信号
cpp
#include <iostream>
#include <csignal>
void sigfpe_handler(int signal) {
std::cout << "浮点异常" << std::endl;
exit(1);
}
int main() {
signal(SIGFPE, sigfpe_handler);
int a = 10;
int b = 0;
int c = a / b;
std::cout << "c = " << c << std::endl;
return 0;
}5.2 处理 SIGSEGV 信号
cpp
#include <iostream>
#include <csignal>
void sigsegv_handler(int signal) {
std::cout << "段错误" << std::endl;
exit(1);
}
int main() {
signal(SIGSEGV, sigsegv_handler);
int* ptr = nullptr;
*ptr = 10;
return 0;
}6. 信号处理和资源清理
6.1 使用 atexit 函数
cpp
#include <iostream>
#include <csignal>
#include <cstdlib>
void cleanup() {
std::cout << "清理资源" << std::endl;
}
void sigint_handler(int signal) {
std::cout << "接收到 SIGINT 信号" << std::endl;
exit(0);
}
int main() {
atexit(cleanup);
signal(SIGINT, sigint_handler);
std::cout << "按 Ctrl+C 发送 SIGINT 信号" << std::endl;
while (true) {
sleep(1);
}
return 0;
}7. 示例:综合运用
现在,让我们看一个综合运用各种信号处理特性的例子:
cpp
#include <iostream>
#include <csignal>
#include <unistd.h>
#include <cstdlib>
bool running = true;
void sigint_handler(int signal) {
std::cout << "\n接收到 SIGINT 信号" << std::endl;
running = false;
}
void sigterm_handler(int signal) {
std::cout << "接收到 SIGTERM 信号" << std::endl;
running = false;
}
void sigalrm_handler(int signal) {
std::cout << "定时器到期" << std::endl;
}
void cleanup() {
std::cout << "清理资源" << std::endl;
}
int main() {
atexit(cleanup);
signal(SIGINT, sigint_handler);
signal(SIGTERM, sigterm_handler);
signal(SIGALRM, sigalrm_handler);
std::cout << "程序 PID: " << getpid() << std::endl;
std::cout << "按 Ctrl+C 发送 SIGINT 信号" << std::endl;
std::cout << "使用 kill 命令发送 SIGTERM 信号" << std::endl;
std::cout << "设置 5 秒定时器" << std::endl;
alarm(5);
int count = 0;
while (running) {
std::cout << "计数: " << count++ << std::endl;
sleep(1);
}
std::cout << "程序正常退出" << std::endl;
return 0;
}小结
C++ 信号处理包括:
信号的基本概念:
- 信号是操作系统向进程发送的异步通知
- 用于处理各种事件,如中断、错误等
signal 函数:
- 用于设置信号处理函数
- 基本语法:
signal(int sig, void (*func)(int))
信号处理函数:
- 处理 SIGINT 信号(Ctrl+C)
- 处理 SIGTERM 信号(终止信号)
- 处理 SIGALRM 信号(定时器信号)
raise 函数:
- 用于向当前进程发送信号
- 基本语法:
raise(int sig)
信号处理和异常:
- 处理 SIGFPE 信号(浮点异常)
- 处理 SIGSEGV 信号(段错误)
信号处理和资源清理:
- 使用
atexit函数注册清理函数 - 在信号处理函数中设置标志位
- 使用
关键概念:
- 信号:操作系统向进程发送的异步通知
- signal 函数:设置信号处理函数
- raise 函数:向当前进程发送信号
- SIGINT:中断信号(Ctrl+C)
- SIGTERM:终止信号
- SIGALRM:定时器信号
- SIGFPE:浮点异常
- SIGSEGV:段错误
掌握信号处理是编写健壮 C++ 程序的重要基础,在后续章节中,我们将学习 C++ 的多线程。