7

複数のスレッドからロギングするための単純なクラスを実装したいと思います。ログを記録したい各オブジェクトは、通常の演算子を使用してメッセージを書き込むことができるostreamオブジェクトを受け取るという考え方があります。望ましい動作は、ストリームがフラッシュされたときにメッセージがログに追加されることです。このようにして、メッセージが他のスレッドからのメッセージによって中断されることはありません。ほとんどのメッセージが少なくとも2ライナーになるため、メッセージを格納するために一時的な文字列ストリームを使用することは避けたいと思います。私が見ているように、これを達成するための標準的な方法は、独自のストリームバッファを実装することですが、これは非常に面倒でエラーが発生しやすいようです。これを行うためのより簡単な方法はありますか?そうでない場合は、カスタムストリームバフに関する優れた記事/ハウツー/ガイドを知っていますか?

前もって感謝します、

Space_C0wbo0y

アップデート:

それはうまくいくようですので、私は自分の答えを追加しました。

4

4 に答える 4

5

log4cppを見てください。マルチスレッドをサポートしています。時間を節約できます。

于 2009-12-09T10:10:40.803 に答える
1

log4cppが重すぎると思い、代わりにBoost.IOStreamsに到達しますか?は?

あなたはlogogを検討したいかもしれません。POSIX、Win32、Win64ではスレッドセーフです。

于 2012-01-25T08:58:15.740 に答える
1

そこで、Boost.IOstreamsを調べました。これが、私が思いついたものです。

class TestSink : public boost::iostreams::sink {
public:
    std::streamsize write( const char * s, std::streamsize n ) {
        std::string message( s, n );
            /* This would add a message to the log instead of cout.
               The log implementation is threadsafe. */
        std::cout << message << std::endl;
        return n;
    }
};

TestSinkストリームバッファを作成するために使用できます(stream_buffer-templateを参照)。すべてのスレッドは独自ののインスタンスを受け取りますがTestSink、すべてTestSinksが同じログに書き込みます。TestSink次のように使用されます。

TestSink sink;
boost::iostreams::stream_buffer< TestSink > testbuf( sink, 50000 );
std::ostream out( &testbuf );

for ( int i = 0; i < 10000; i++ )
    out << "test" << i;

out << std::endl;

ここで重要なのは、ストリームがフラッシュされたとき(または)、またはインスタンスの内部バッファーがいっぱいにTestSink.writeなったときにのみ呼び出されることです(デフォルトのバッファーサイズは40000文字を保持できないため、50000に初期化します)。このプログラムでは、が1回だけ呼び出されます(出力が長すぎてここに投稿できません)。このようにして、一時変数なしで通常の形式のstream-IOを使用してログメッセージを書き込むことができ、ストリームをフラッシュするときにメッセージがログに1つにまとめて投稿されるようにします。std::endlstd::flushstream_bufferTestSink.write

私が考慮していない別の提案/問題がある場合に備えて、私は別の日に質問を開いたままにしておきます。

于 2009-12-09T12:37:49.893 に答える
0

再。あなた自身の反応。これをエラー ログに使用していて、ストリームをフラッシュする前にクラッシュをプログラムする場合、ログは少し役に立ちませんか?

于 2009-12-09T13:20:31.670 に答える