2016-07-28 4 views
0

Boost.Log非同期シンクを使用しています(Asynchronous sink frontendを参照)。適切なシャットダウンを行うには、非同期シンクへのレコードの供給を正常に停止してフラッシュする必要があります。コアにシンクを追加したり削除したりする方法がありますが、クライアントがシンクを取得したり訪問したりする方法はありません。ドキュメントはstop_logging方法、Boost.Logを使用しているときにすべての非同期シンクを停止する方法

void stop_logging(boost::shared_ptr<sink_t>& sink) 
{ 
    boost::shared_ptr<logging::core> core = logging::core::get(); 

    // Remove the sink from the core, so that no records are passed to it 
    core->remove_sink(sink); 

    // Break the feeding loop 
    sink->stop(); 

    // Flush all log records that may have left buffered 
    sink->flush(); 

    sink.reset(); 
} 

を持っていますが、それは特定のsink_t型を取ります。 asynchronous_sinkフロントエンドクラスには、シンクのバックエンドとキューイング戦略のテンプレート引数があります。

template<typename SinkBackendT, 
      typename QueueingStrategyT = unbounded_fifo_queue> 
    class asynchronous_sink; 

私はシンクのいくつかの異なる種類がありますので、私はそれらを保持している汎用コンテナを持っていると思いますので、私はそれ以上の単純な反復処理をすることができますし、コンテナ内の各シンク用stop_loggingを呼び出します。

これは、Boost.Logで提供されているインタフェースのために、私が対処しなければならないC++のテンプレートデータ構造に関する実際の質問です。私がBoost.Logコアに追加した非同期シンクを追跡するのに使う良いデータ構造は何ですか?私はシャットダウン時にstop_loggingと呼ぶことができるので、私は1つ必要です。

私の最初の簡単なアプローチは、boost::anyオブジェクトのベクトルを持つことです。しかし、それはむしろ面倒で面倒なことです。私は合理的なアプローチは、stop_loggingを呼び出すラムダメソッドである関数オブジェクトのベクトルを持つことになると考えています。しかし、私はテンプレートの種類で失われ、これを行う方法を知らない。

何か助けていただきありがとうございます。 ありがとう!

答えて

1

あなたが提案したように、最も直接的な解決策は、関数オブジェクトを持つコンテナを持つことです。例:この例では

std::vector< std::function< void() > > stop_functions; 

// For every asynchronous sink you add 
stop_functions.emplace_back([sink]() 
{ 
    sink->flush(); 
    sink->stop(); 
}); 

sinkを使用すると、ログコアに追加する起こるasynchronous_sinkのすべてのインスタンスへのポインタであることができます。あなたのアプリケーションは、あなただけのコンテナに保存されたすべての関数を呼び出す必要が終了した場合:

for (auto& stop : stop_functions) 
    stop(); 

しかし、allowsはこのプロセスを少し単純化するBoost.Signals2ライブラリがあります。あなたは信号を作成し、それはこのように機能を接続することができます。

boost::signals2::signal< void() > stop_signal; 

// For every asynchronous sink you do 
stop_signal.connect([sink]() 
{ 
    sink->flush(); 
    sink->stop(); 
}); 

は次に信号を呼び出すことによって、あなたは効果的にすべてのシンクを停止し、すべての接続された機能オブジェクトを呼び出すことになります。いずれの場合も

stop_signal(); 

、あなたが好きな関数オブジェクトを作成するためにstd::bindまたは任意の他の手段を使用することができます。不可欠な部分は、シンクフロントエンドへのポインタをそのタイプとともに関数オブジェクトに保存することです。

関連する問題