C++信號處理
信號是由操作係統,可以提早終止一個程序傳送到一個過程中的中斷。可以通過按Ctrl+C在UNIX,LINUX,Mac OS X或Windows係統上產生中斷。
不能捕獲程序的信號,但存在著而可以在程序中捕捉並可以采取基於信號適當的動作的信號如下麵的列表。這些信號在C++頭文件<csignal>定義。
信號 | 描述 |
---|---|
SIGABRT | 異常終止程序,如調用abort |
SIGFPE | 錯誤的算術運算,例如除零或導致溢出的操作 |
SIGILL | 檢測非法指令 |
SIGINT | 接收到交互注意信號 |
SIGSEGV | 一個非法訪問存儲 |
SIGTERM | 發送到程序的終止請求 |
signal() 函數:
C++信號處理庫提供函數來捕獲信號突發事件。以下是signal()函數的語法:
void (*signal (int sig, void (*func)(int)))(int);
保持簡單,這個函數接收兩個參數:第一個參數是一個整數,代表信號的號;第二個參數是一個指向信號處理函數。
讓我們寫一個簡單的C++程序,使用signal()函數捕獲到SIGINT信號。不管信號在程序中捕獲,必須使用信號函數來注冊的信號,並將其與信號處理程序相關聯。看看下麵的例子:
#include <iostream> #include <csignal> using namespace std; void signalHandler( int signum ) { cout << "Interrupt signal (" << signum << ") received. "; // 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. "; // 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.