C++ 信号处理学习笔记

一、信号概述

在计算机操作系统中,信号(Signal)是由操作系统(或者特权进程)向应用进程发送的一种消息。信号可以用于通知进程发生了某种事件,例如:进程收到了一个未捕获的异常、用户按下了特殊的终端字符,等等。

二、如何处理信号

在C++中,我们可以使用signal()函数来注册一个信号处理程序。signal()的原型如下:

Copy Code
void (*signal(int signum, void (*handler)(int))) (int);

其中,第一个参数signum表示要注册的信号编号(可以参考UNIX/LINUX系统中定义的信号常量),第二个参数handler表示信号处理程序的回调函数指针。

下面是一个简单的处理SIGINT信号(例如Ctrl+C)的例子:

c++Copy Code
#include <iostream> #include <unistd.h> #include <cstdlib> #include <cstdio> #include <csignal> using namespace std; void signalHandler(int signalNum) { cout << "接收到信号:" << signalNum << endl; exit(signalNum); } int main() { signal(SIGINT, signalHandler); // 注册信号处理函数 cout << "开始循环..." << endl; while(true) { sleep(1); } return 0; }

通过这个例子,当你在运行程序的时候按下了Ctrl+C键,程序将会输出以下内容并且退出:

Copy Code
接收到信号:2

三、信号处理程序的注意事项

在信号处理程序中,我们需要注意以下几点:

  • 不要过多地处理信号,以免影响程序的性能。
  • 在信号处理程序中,不应该调用任何不可重入函数(例如printf、malloc等)。
  • 在信号处理程序中,尽量不要使用全局变量,也不要使用静态变量。

四、实例:基于信号的定时器

下面是一个基于信号的简单定时器实现,我们通过发送信号来模拟时间的流逝:

c++Copy Code
#include <iostream> #include <cstdlib> #include <cstdio> #include <csignal> #include <unistd.h> using namespace std; const int SECONDS = 5; void signalHandler(int signalNum) { cout << "接收到信号:" << signalNum << endl; if(signalNum == SIGALRM) { // 如果是定时器信号 cout << "\t 定时到达!" << endl; alarm(SECONDS); // 重新启动定时器 } } int main() { signal(SIGALRM, signalHandler); // 注册信号处理函数 cout << "开始计时..." << endl; int restTime = alarm(SECONDS); // 启动定时器 while(restTime > 0) { restTime = sleep(restTime); } return 0; }

通过这个例子,我们可以模拟一个5秒钟的定时器,每当定时时间到达的时候,程序将会输出以下信息:

Copy Code
接收到信号:14 定时到达!

五、总结

本文简单介绍了C++中的信号处理机制,并通过两个例子来说明了如何使用信号处理程序。希望对你有所帮助!