美文网首页
系统信号处理

系统信号处理

作者: 长不胖的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