信號處理

2018-08-12 22:03 更新

信號處理

信號是由操作系統(tǒng)傳遞到進程的中斷,它可以提前終止一個程序。在 UNIX,LINUX,Mac OS X 或 Windows 系統(tǒng)上,你可以通過按 Ctrl+C 產(chǎn)生一個中斷。

有的信號不能被程序捕獲到,但是下面列出的信號,你可以在程序中捕捉它們,并且可以基于這些信號進行相應的操作。這些信號定義在 C++ 頭文件<csignal>中。

信號 描述
SIGABRT 程序的異常終止,例如調用 abort
SIGFPE 一個錯誤的算術運算,例如除以零或運算結果溢出。
SIGILL 檢測到非法指令。
SIGINT 接收到交互注意信號。
SIGSEGV 一個非法的存儲訪問。
SIGTERM 發(fā)送給程序的終止請求信號。

signal() 函數(shù)

C++ 信號處理庫提供 signal 函數(shù)來捕獲意外事件。以下是 signal() 函數(shù)的語法:

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

簡單來說,這個函數(shù)接收兩個參數(shù):第一個參數(shù)是一個整數(shù),表示信號號碼;第二個參數(shù)是一個指向信號處理函數(shù)的指針。

讓我們用 signal() 函數(shù)寫一個簡單的 C++ 程序,用它來捕捉 SIGINT 信號。不管你想在程序中捕獲什么信號,你必須使用 signal 函數(shù)注冊該信號,并將其與信號處理程序相關聯(lián)。 例子如下所示:

    #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;
    }

當上述代碼編譯和執(zhí)行后,將會產(chǎn)生以下的結果:

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

現(xiàn)在,按 Ctrl+C 來中斷這個程序,你會看到程序將捕獲的信號,并會通過打印展示出來,如下所示:

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

raise() 函數(shù)

您可以通過 raise() 函數(shù)生成信號,它用一個整數(shù)的信號編號作為參數(shù),語法如下所示。

    int raise (signal sig);

這里的 sig 是要發(fā)送的信號編號,這些信號是:SIGINT,SIGABRT,SIGFPE,SIGILL,SIGSEGV,SIGTERM,SIGHUP。以下是我們使用 raise() 函數(shù)從程序內部發(fā)出一個信號的例子:

    #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;
    }

當上述代碼編譯和執(zhí)行后,將會產(chǎn)生以下的結果,并且這些結果會自動出現(xiàn):

    Going to sleep....
    Going to sleep....
    Going to sleep....
    Interrupt signal (2) received.
以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號