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 次瀏覽

啟動您的職業生涯

完成課程獲得認證

開始學習
廣告