信号处理
#include <iostream> #include <csignal> // 信号函数库 #include <windows.h> // Linux,Unix 系统要引入 <unistd.h> using namespace std; // 信号处理函数,signum 是信号编号,这个相当于一个回调函数,同时相当于覆写了底层的库函数进行个性化信息的输出 void signalHandler(int signum) { cout << "Interrupt signal (" << signum << ") received." << endl; // 输出个性化信息 exit(signum); // 终止程序 } int main() { // 注册信号 SIGINT, 信号被捕捉到之后指向信号处理函数 signalHandler,这个函数要写在前面(只要接收到中断信号输入就会被这个 signal 函数捕捉到) signal(SIGINT, signalHandler); // 模拟程序在执行 while (1) { cout << "Going to sleep...." << endl; Sleep(1000); } system("pause"); return 0; }
按 Ctrl + C 进行信号中断,不进行信号处理时运行:(注意:这里运行的时候要在命令行中运行才看得到,如果在Visual Studio软件中运行程序的话窗口会一闪而过,看不到结果的)
进行信号函数处理后的结果:
为什么这里会输出 Interrupt signal (2) received. 这里会输出 2 呢?因为键盘输入的中断信号 Ctrl + C 对应的中断信号的编号就是 2,我们查看 C++ 的源代码 SIGINT
如果还有疑问,那么我们使用 g++ -E main.cpp > main.p 命令来编译一下程序,就可以看到编译后的文件信息:
可以看到被编译后的文件,把 SIGINT 常量编译成了 2,这样就证明了 Ctrl + C 的中断信号的编号就是 2,在程序不断执行的时候,当用户按下 Ctrl + C 键之后,被signal()函数捕捉到信号中断,获取信号中断编号以及函数指针指向signalHandler信号中断处理函数,在这个函数中可以进行个性化的信息输出操作。
************************************************************** 以上是需要外部 按下 Ctrl + C 键才会触发信号中断,改变一下程序:不需要按下这个键,当满足一定条件时自动触发!使用 raise()函数 ********************************************
#include <iostream> #include <csignal> // 信号函数库 #include <windows.h> // Linux,Unix 系统要引入 <unistd.h> using namespace std; // 信号处理函数,signum 是信号编号,这个相当于一个回调函数,同时相当于覆写了底层的库函数进行个性化信息的输出 void signalHandler(int signum) { cout << "Interrupt signal (" << signum << ") received." << endl; // 输出个性化信息 exit(signum); // 终止程序 } int main() { int i = 0; // 注册信号 SIGINT, 信号被捕捉到之后指向信号处理函数 signalHandler,这个函数要写在前面(只要接收到中断信号输入就会被这个 signal 函数捕捉到) signal(SIGINT, signalHandler); // 模拟程序在执行 while (++i) { cout << "Going to sleep...." << endl; /* 信号生成函数:相当于不需要外部按下 Ctrl + C 按键的情况下,当程序满足一定的条件时,自动生成一个信号中断命令 去自动调用 signalHandler 信号处理函数进行信号中断处理 */ if (i == 3) // 循环 3 次之后就中断 { raise(SIGINT); // 满足条件,这个函数执行之后,会自动去找 signal 函数,把信号中断编号给它,接下来由 signal 函数去处理后续的事情 } Sleep(1000); } system("pause"); return 0; }
在命令行中执行:发现没有按下任何按键,在程序循环了 3 次之后自动就中断了!实现了自动中断,其实 raise 函数就是一个信号生成函数