2017-08-14 120 views
0

我想一個信號處理程序添加到我的提振io_service對象,允許應用程序完全在用戶按下Ctrl-C來關閉io_service對象。這當然是通過停止循環,這樣的事情很容易做到的:加速ASIO處理不繼續運行

boost::asio::io_service service; 
boost::asio::signal_set signals{ service, SIGINT, SIGTERM }; 

signals.async_wait(std::bind(&boost::asio::io_service::stop, &service)); 

這通常停止循環,使析構函數做他們的日常清理行爲。

的問題是,一旦應用程序運行出來工作也不會停止,因爲信號處理程序仍然有註冊的處理程序,因此io_service對象從未停止運行。

我還沒有找到解決這個乾淨的方法。我當然可以做自己的信號處理,然後停止循環,但是這種方式挫敗了使用boost(可移植性)的想法。

+0

爲什麼不能申請調用'signals.cancel()'當它失去工作? – kenba

+0

因爲應用程序不知道它什麼時候用完了。唯一知道是否有更多工作可用的是io_service。 –

+0

你使用'io_service'作爲線程池嗎?你到底在做什麼? –

回答

0

在下面的代碼,http_server具有「監聽套接字」接受多個連接。監聽插座不斷運行async_accept,因此io_service永遠不會停止工作。該http_server.shutdown()功能關閉監聽套接字和所有打開的連接,所以io_service有沒有更多的工作,並停止運行:

void handle_stop(ASIO_ERROR_CODE const&, // error, 
       int, // signal_number, 
       http_server_type& http_server) 
{ 
    std::cout << "Shutting down" << std::endl; 
    http_server.shutdown(); 
} 

... 

ASIO::io_service io_service; 
http_server_type http_server(io_service); 

... 


// The signal set is used to register termination notifications 
ASIO::signal_set signals_(io_service); 
signals_.add(SIGINT); 
signals_.add(SIGTERM); 
#if defined(SIGQUIT) 
signals_.add(SIGQUIT); 
#endif // #if defined(SIGQUIT) 

// register the handle_stop callback 
signals_.async_wait([&http_server] 
    (ASIO_ERROR_CODE const& error, int signal_number) 
{ handle_stop(error, signal_number, http_server); }); 

... 

io_service.run(); 
std::cout << "io_service.run complete, shutdown successful" << std::endl; 

這種方法也適用於線程池,請參見:thread_pool_http_server.cpp