2017-08-14 16 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

できないのはなぜアプリケーションio_serviceはありませんより多くの仕事を持っているし、実行を停止してhttp_server.shutdown()機能は、リスニングソケットと、開いているすべての接続を閉じます作業がなくなったときに 'signals.cancel()'を呼び出します。 – kenba

+0

このアプリケーションでは、作業が不足したときはわかりません。より多くの作業が利用可能かどうかを知る唯一のものは、io_serviceです。 –

+0

'io_service'をスレッドプールとして使用していますか?何を正確にしていますか? –

答えて

0

http_serverには、複数の接続を受け入れるための「リスニングソケット」があります。リスニングソケットは常にasync_acceptを実行しますので、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

関連する問題