信號是由操作系統傳給進程的中斷,會提早終止一個程序。在UNIX、LINUX、Mac OS或windows系統上,可以通過按Ctrl+c產生中斷。有些信號不能被程序捕獲,但是下表所列信號可以在程序中被捕獲,并可以基于信號采取適當的動作。這些信號是定義在C++頭文件<csignal>中。
信號 | 描述 |
SIGABRT | 程序的異常終止,如調用abort |
SIGFPE | 錯誤的算術運算,比如除以零或者導致溢出的操作 |
SIGILL | 檢測非法指令 |
SIGINT | 接受到交互注意信號 |
SIGSEGV | 非法訪問內存 |
SIGTERM | 發送到程序的終止請求 |
?
signal()函數
C++信號處理庫提供了signal函數,用來捕獲突發事件
void (*signal (int sig,void (*func)(int)))(int);
這個函數接收兩個參數:第一個參數是一個整數,代表了信號的編號;第二個參數是一個指向信號處理函數的指針。
/*** signal.cpp ***/ #include<iostream> #include<csignal> #include<unistd.h> #include<cstdlib>using namespace std;void signalHandler(int signum) {cout << "Interrupt signal (" << signum << ") received.\n";exit(signum); }int main() {signal(SIGINT,signalHandler);while(1){cout << "Going to sleep..." << endl;sleep(1);}return 0; }
運行結果:
exbot@ubuntu:~/wangqinghe/C++/20190816$ g++ signal.cpp -o signal
exbot@ubuntu:~/wangqinghe/C++/20190816$ ./signal
Going to sleep...
Going to sleep...
Going to sleep...
Going to sleep...
^CInterrupt signal (2) received.
?
raise()函數
使用函數raise()生成信號,該函數帶有一個整數信號編號作為參數,語法如下:
int raise(signal sig);
?
在這里,sig是要發送的信號的編號,這些信號包括:SIGINT,SIGBABRT、SIGFPE、SIGILL、SIGSEGV、SIGTERM、SIGHUP。
/*** raise.cpp ***/ #include<iostream> #include<csignal> #include<unistd.h> #include<cstdlib>using namespace std;void signalHandler(int signum) {cout << "Interrupt signal (" << signum << ") received." << endl;exit(signum); }int main() {int i = 0;signal(SIGINT,signalHandler);while(++i){cout << "Going to sleep..." << endl;if(3 == i){raise(SIGINT);}sleep(1);}return 0; }
運行結果:
exbot@ubuntu:~/wangqinghe/C++/20190816$ g++ raise.cpp -o raise
exbot@ubuntu:~/wangqinghe/C++/20190816$ ./raise
Going to sleep...
Going to sleep...
Going to sleep...
Interrupt signal (2) received.