C 语言信号处理
外观
简介
信号处理是C语言标准库(<signal.h>
)提供的一种进程间通信机制,允许操作系统或用户进程向目标进程发送异步事件通知。信号可以用于处理异常、中断请求或实现简单的进程控制。在UNIX/Linux系统中,信号是系统级事件的基本通知方式。
信号处理的核心功能包括:
- 发送信号(如通过
kill()
系统调用) - 捕获并自定义信号处理行为
- 忽略或恢复默认信号行为
信号类型
常见标准信号(定义在<signal.h>
中):
信号名 | 值 | 描述 |
---|---|---|
SIGINT |
2 | 终端中断(如Ctrl+C) |
SIGSEGV |
11 | 无效内存访问 |
SIGTERM |
15 | 终止请求 |
SIGALRM |
14 | 定时器超时 |
基本用法
信号处理函数
使用signal()
函数注册信号处理器:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void handler(int sig) {
printf("Received signal: %d\n", sig);
}
int main() {
signal(SIGINT, handler); // 注册SIGINT处理器
while(1) {
printf("Running...\n");
sleep(1);
}
return 0;
}
输出示例:
Running... Running... ^CReceived signal: 2 # 用户按下Ctrl+C Running... ...
高级信号处理
更安全的sigaction()
函数:
struct sigaction sa;
sa.sa_handler = handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGINT, &sa, NULL);
实际案例
定时器实现
使用SIGALRM
创建简单定时器:
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
void alarm_handler(int sig) {
printf("Timer expired!\n");
}
int main() {
signal(SIGALRM, alarm_handler);
alarm(5); // 设置5秒定时器
pause(); // 等待信号
return 0;
}
多线程信号处理
在多线程程序中,信号处理需特别注意:
pthread_sigmask(SIG_BLOCK, &mask, NULL); // 阻塞信号
// 创建线程...
pthread_sigmask(SIG_UNBLOCK, &mask, NULL); // 在主线程处理信号
信号处理流程
数学基础
信号处理涉及中断概率计算。假设信号到达服从泊松分布: 其中:
- 为单位时间平均信号数
- 为实际到达信号数
注意事项
1. 信号处理函数应是可重入的(避免使用非异步安全函数如printf()
)
2. 某些信号(如SIGKILL
)不能被捕获或忽略
3. 信号可能中断系统调用(需检查errno == EINTR
)
扩展阅读
- UNIX信号机制发展历史
- 实时信号(
SIGRTMIN
到SIGRTMAX
) - 信号与进程状态的关系