C++中的信号处理


信号是由操作系统传递给进程的中断,它可能提前终止程序。您可以在UNIX、LINUX、Mac OS X或Windows系统上按Ctrl+C来生成中断。

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

信号
描述
SIGABRT
程序异常终止,例如调用abort
SIGFPE
算术运算错误,例如除以零或导致溢出的运算。
SIGILL
检测到非法指令。
SIGINT
收到交互式中断信号。
SIGSEGV
无效的存储器访问。
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 << "Interrupt signal (" << signum << ") received.\n";
   // cleanup and close up stuff here
   // terminate program
   exit(signum);
}
int main () {
   // register signal SIGINT and signal handler
   signal(SIGINT, signalHandler);
   while(1) {
      cout << "Going to sleep...." << 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 << "Interrupt signal (" << signum << ") received.\n";
   // cleanup and close up stuff here
   // terminate program
   exit(signum);
}
int main () {
   int i = 0;
   // register signal SIGINT and signal handler
   signal(SIGINT, signalHandler);
   while(++i) {
      cout << "Going to sleep...." << endl;
      if( i == 3 ) {
         raise( SIGINT);
      }
      sleep(1);
   }
   return 0;
}

输出

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

更新于:2019年7月30日

469 次浏览

启动您的职业生涯

完成课程获得认证

开始学习
广告