C++信号处理
信号是由操作系统传给进程的中断,会提早终止一个程序。在 LINUX 或 Windows 系统上,可以通过按 Ctrl+C 产生中断。有些信号不能被程序捕获,但是下表所列信号可以在程序中捕获,并可以基于信号采取适当的动作。这些信号是定义在 C++ 头文件 <csignal>
中。
使用 signal() 函数捕获 SIGINT 信号, 函数的定义signal(registered signal, signal handler)
接收两个参数:第一个参数代表了信号的编号;第二个参数是一个指向信号处理函数的指针。不管您想在程序中捕获什么信号,您都必须使用 signal 函数来注册信号,并将其与信号处理函数关联。
使用函数 raise() 生成信号,该函数定义int raise (signal sig)
带有一个整数信号编号作为参数
#include <cstdio>
#include <csignal>
#include <cstdlib>
#if defined(__linux__)
#include <unistd.h>
#elif defined(_WIN32)
#include <Windows.h>
// 可恶!VC中的Sleep函数头字母S是大写的,而且单位是毫秒
#define sleep(n) Sleep(n*1000)
#endif
void signalHandler(int sign) {
std::printf("interrupt signal (%d) received, abort.\n", sign);
exit(sign);
}
int main() {
// 注册信号
signal(SIGTERM, signalHandler);
signal(SIGINT, signalHandler);
// 业务循环
while (true) {
std::printf("Going to sleep 1 second..\n");
sleep(1);
}
}
可捕获的信号类型如下:
- SIGABRT 程序的异常终止,如调用 abort。
- SIGFPE 错误的算术运算,比如除以零或导致溢出的操作。
- SIGILL 检测非法指令。
- SIGINT 程序终止(interrupt)信号。普通的kill操作。
- SIGSEGV 非法访问内存。
- SIGTERM 发送到程序的终止请求。前台执行时Ctrl+C操作。
编译执行下试试,尝试按了Ctrl+C按键和使用kill命令,进程均正常接收到信号退出。
raveh@DESKTOP-MBGF84O:~/work/cpp$ g++ Day05.cpp
raveh@DESKTOP-MBGF84O:~/work/cpp$ ./a.out
Going to sleep 1 second..
Going to sleep 1 second..
Going to sleep 1 second..
^Cinterrupt signal (2) received, abort.
raveh@DESKTOP-MBGF84O:~/work/cpp$
raveh@DESKTOP-MBGF84O:~/work/cpp$
raveh@DESKTOP-MBGF84O:~/work/cpp$
raveh@DESKTOP-MBGF84O:~/work/cpp$ ./a.out
Going to sleep 1 second..
Going to sleep 1 second..
Going to sleep 1 second..
interrupt signal (15) received, abort.
# windows下调试
Going to sleep 1 second..
Going to sleep 1 second..
Going to sleep 1 second..
interrupt signal (2) received, abort.
D:\workspace\cpp\VSProjects\hiCPP\bin\Win32\Debug\hiCPP.exe (进程 2508)已退出,代码为 2。
按任意键关闭此窗口. . .
©raveh.net