1. Linux信号机制概述
在Linux系统中,信号是一种重要的进程间通信机制,用于通知进程发生了特定事件。就像我们日常生活中遇到的各种信号(如交通信号灯、手机来电提醒)一样,操作系统通过信号来告知进程需要处理的事件。
信号处理通常分为三个阶段:
- 信号产生:某个事件触发了信号(如用户按下Ctrl+C)
- 信号保存:进程暂时存储接收到的信号
- 信号执行:进程在合适的时间处理信号
1.1 信号的基本特性
Linux系统中的信号具有以下特点:
- 每个信号都有唯一的编号和宏定义名称(如SIGINT对应2号信号)
- 信号分为普通信号(1-31)和实时信号(34以上)
- 进程可以预先设置对信号的处理方式
信号的处理方式有三种:
- 默认动作:执行系统预设的行为(如终止进程)
- 忽略信号:完全不做任何处理
- 自定义处理:执行用户定义的函数
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 信号的产生与处理
2.1 键盘输入与信号
当我们按下Ctrl+C时,终端会向前台进程发送SIGINT(2)信号。这个过程涉及以下步骤:
- 键盘输入被硬件检测到并产生中断
- 操作系统通过中断向量表找到对应的处理程序
- 终端驱动程序识别组合键并生成相应信号
- 操作系统将信号传递给前台进程
cpp复制#include <iostream>
#include <unistd.h>
#include <signal.h>
void handler(int sig) {
std::cout << "Received signal: " << sig << std::endl;
}
int main() {
signal(SIGINT, handler); // 捕获Ctrl+C
while(1) {
std::cout << "Running..." << std::endl;
sleep(1);
}
return 0;
}
2.2 信号处理函数
signal()函数用于设置信号处理方式:
cpp复制#include <signal.h>
void (*signal(int sig, void (*func)(int)))(int);
参数说明:
- sig:信号编号
- func:处理函数指针(可以是SIG_DFL、SIG_IGN或自定义函数)
注意:signal()函数在不同Unix系统中有行为差异,建议使用更现代的sigaction()函数。
3. 信号的发送方式
3.1 kill系统调用
kill()函数可以向指定进程发送信号:
cpp复制#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
实现一个简单的kill命令:
cpp复制#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <signal.h>
int main(int argc, char* argv[]) {
if(argc != 3) {
std::cerr << "Usage: " << argv[0] << " <signal> <pid>" << std::endl;
return 1;
}
