美文网首页
系统信号处理

系统信号处理

作者: 长不胖的Garfield | 来源:发表于2017-01-13 15:07 被阅读0次

    为什么要有信号处理

    程序在执行过程中可能会被系统关闭,譬如在命令行执行时用户按下CTRL+C终止执行,或者在进程管理时直接终止,为了保证程序能够正常退出,来释放所有占用的资源,做一些必要的退出前处理,都需要能够捕获到这些信号并进行处理。

    C++标准的处理方法

    C++提供了signal方法用来安装一个信号处理handler来替换默认的处理handler:

    //Visual Studio 2015中的定义
    typedef void (__CRTDECL* _crt_signal_t)(int); //处理handler定义
    
     _crt_signal_t __cdecl signal(_In_ int _Signal, _In_opt_ _crt_signal_t _Function);
    

    Boost.Asio中的signal_set

    Boost.Asio中定义了signal_set来进行系统信号的响应,其使用io_service和要相应的信号构造,提供了如下方法:

    • add:添加一个信号
    • remove:移除一个信号
    • clear:移除其所有信号
    • async_wait:启动异步操作等待接收信号

    信号的通知

    信号发生后会被排队到队列,在有async_wait的情况下会发出通知,当多个信号发生,也会一个一个地通知,如果信号被从signal_set中移除则对应的通知会被抛弃。

    使用方法

    示例如下:

    void handler( const boost::system::error_code& error, int signal_number)
    { 
     if (!error) 
     { 
      // 信号发生了
      }
    }
    ...
    // 构造signal set 来接收进程终止消息.
    boost::asio::signal_set signals(io_service, SIGINT, SIGTERM);
    // 启动异步操作等待信号发生
    signals.async_wait(handler);
    

    注意事项

    相同的信号可以被注册到不同的signal_set,当信号发生时所有signal_set的处理handler均会被调用;多次注册只是在Boost.Asio中能够使用;如果使用signal_set就不要再使用其它方式注册信号处理handler了。

    Boost.Asio中如何使用

    当接收到对应信号后就需要进行清理流程了,如果启动了io_service.run,可以在清理流程中调用io_service.stop,这样io_service.run会尽可能快地退出,所有的异步操作等都会被抛弃,示例如下:

    class server
    {
    public:
        server(unsigned short port)
            :signals_(io_,SIGINT,SIGTERM),
            acceptor_(io_,tcp::endpoint(tcp::v4(),port)),
            socket_(io_)
        {
     
        }
        ~server() { io_.stop(); };
        void listen()
        { 
          
            //当接收到中断信号就停止服务执行退出流程
            signals_.async_wait([this](const boost::system::error_code& ec,int signal_number){
                if (!ec)
                {
                    io_.stop();
                    std::cout<<"server stopping\n";
                }
            });
     
            do_accept();
            io_.run();
        }
     
        void do_accept()
        {
            acceptor_.async_accept(socket_, [this](boost::system::error_code ec) {
                if (!ec)
                {
                   ......
                }
                else
                {
                    std::cerr << ec.message() << std::endl;
                }
                do_accept();//继续发起accept流程阻止run退出
            });
        }
    private:
        boost::asio::io_service io_;
        boost::asio::signal_set signals_;
     
        tcp::acceptor acceptor_;
        tcp::socket   socket_;
    };
    
    

    相关文章

      网友评论

          本文标题:系统信号处理

          本文链接:https://www.haomeiwen.com/subject/thrsbttx.html