信号处理

2018-08-12 22:03 更新

信号处理

信号是由操作系统传递到进程的中断,它可以提前终止一个程序。在 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.
以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号