C++ 信号处理怎么实现?

文章导读
Previous Quiz Next 信号是由操作系统发送给进程的中断,可以使程序提前终止。在 UNIX、LINUX、Mac OS X 或 Windows 系统上,你可以通过按 Ctrl+C 来生成中断。
📋 目录
  1. signal() 函数
  2. raise() 函数
A A

C++ 信号处理



Previous
Quiz
Next

信号是由操作系统发送给进程的中断,可以使程序提前终止。在 UNIX、LINUX、Mac OS X 或 Windows 系统上,你可以通过按 Ctrl+C 来生成中断。

有些信号无法被程序捕获,但以下是一些可以在程序中捕获并根据信号采取相应行动的信号列表。这些信号在 C++ 头文件 中定义。

序号 信号 & 描述
1

SIGABRT

程序异常终止,例如调用 abort

2

SIGFPE

错误的算术运算,例如除以零或导致溢出的运算。

3

SIGILL

检测到非法指令。

4

SIGINT

接收到交互式注意信号。

5

SIGSEGV

对存储器的无效访问。

6

SIGTERM

发送给程序的终止请求。

signal() 函数

C++ 信号处理库提供了 signal 函数来捕获意外事件。signal() 函数的语法如下 −

void (*signal (int sig, void (*func)(int)))(int); 

简单来说,此函数接收两个参数:第一个参数是一个整数,表示信号编号;第二个参数是指向信号处理函数的指针。

让我们编写一个简单的 C++ 程序,使用 signal() 函数捕获 SIGINT 信号。无论你想在程序中捕获什么信号,都必须使用 signal 函数注册该信号并将其与信号处理程序关联。查看以下示例 −

#include <iostream>
#include <csignal>

using namespace std;

void signalHandler( int signum ) {
   cout << "中断信号 (" << signum << ") 已接收。\n";

   // 在此处进行清理和关闭操作  
   // 终止程序  

   exit(signum);  
}

int main () {
   // 注册信号 SIGINT 和信号处理程序  
   signal(SIGINT, signalHandler);  

   while(1) {
      cout << "准备休眠...." << endl;
      sleep(1);
   }

   return 0;
}

上述代码编译并执行后,会产生以下结果 −

Going to sleep....
Going to sleep....
Going to sleep....

现在,按 Ctrl+C 中断程序,你会看到程序捕获信号并打印类似以下内容后退出 −

Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.

raise() 函数

你可以使用 raise() 函数生成信号,该函数接受一个整数信号编号作为参数,其语法如下。

int raise (signal sig);

这里,sig 是要发送的信号编号,可以是 SIGINT、SIGABRT、SIGFPE、SIGILL、SIGSEGV、SIGTERM、SIGHUP 中的任何一个。以下示例使用 raise() 函数在内部引发信号 −

#include <iostream>
#include <csignal>

using namespace std;

void signalHandler( int signum ) {
   cout << "中断信号 (" << signum << ") 已接收。\n";

   // 在此处进行清理和关闭操作  
   // 终止程序  

   exit(signum);  
}

int main () {
   int i = 0;
   // 注册信号 SIGINT 和信号处理程序  
   signal(SIGINT, signalHandler);  

   while(++i) {
      cout << "准备休眠...." << endl;
      if( i == 3 ) {
         raise( SIGINT);
      }
      sleep(1);
   }

   return 0;
}

上述代码编译并执行后,会产生以下结果并自动退出 −

Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.