信号处理
信号是由操作系统传递到进程的中断,它可以提前终止一个程序。在 UNIX,LINUX,Mac OS X 或 Windows 系统上,你可以通过按 Ctrl+C 产生一个中断。
有的信号不能被程序捕获到,但是下面列出的信号,你可以在程序中捕捉它们,并且可以基于这些信号进行相应的操作。这些信号定义在 C++ 头文件<csignal>中。
| 信号 | 描述 | 
|---|---|
| SIGABRT | 程序的异常终止,例如调用 abort | 
| SIGFPE | 一个错误的算术运算,例如除以零或运算结果溢出。 | 
| SIGILL | 检测到非法指令。 | 
| SIGINT | 接收到交互注意信号。 | 
| SIGSEGV | 一个非法的存储访问。 | 
| SIGTERM | 发送给程序的终止请求信号。 | 
signal() 函数
C++ 信号处理库提供 signal 函数来捕获意外事件。以下是 signal() 函数的语法:
    void (*signal (int sig, void (*func)(int)))(int); 简单来说,这个函数接收两个参数:第一个参数是一个整数,表示信号号码;第二个参数是一个指向信号处理函数的指针。
让我们用 signal() 函数写一个简单的 C++ 程序,用它来捕捉 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.