7

我想实现一个简单的类来从多个线程进行日志记录。这里的想法是,每个想要记录内容的对象都会接收一个 ostream-object,它可以使用通常的运算符向该对象写入消息。所需的行为是,在刷新流时将消息添加到日志中。这样,消息就不会被来自其他线程的消息打断。我想避免使用临时字符串流来存储消息,因为这会使大多数消息至少包含两个行。在我看来,实现这一点的标准方法是实现我自己的流缓冲区,但这似乎非常麻烦且容易出错。有没有更简单的方法来做到这一点?如果没有,您知道关于自定义流缓冲区的好文章/操作方法/指南吗?

提前致谢,

Space_C0wbo0y

更新:

由于它似乎有效,我添加了我自己的答案。

4

4 回答 4

5

看看log4cpp;他们有一个多线程支持。它可以节省您的时间。

于 2009-12-09T10:10:40.803 回答
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仅在流被刷新(std::endlstd::flush)时调用,或者当stream_buffer实例的内部缓冲区已满时(默认缓冲区大小不能容纳 40000 个字符,因此我将其初始化为 50000)。在这个程序中,TestSink.write只调用一次(输出太长,无法在此处发布)。这样,我可以使用普通格式的流 IO 编写日志消息,而无需任何临时变量,并确保在刷新流时将消息一次性发布到日志中。

如果有我没有考虑过的不同建议/问题,我将在另一天留下这个问题。

于 2009-12-09T12:37:49.893 回答
1

你认为 log4cpp 太重了,你用 Boost.IOStreams 代替?嗯?

您不妨考虑logog。它对于 POSIX、Win32 和 Win64 是线程安全的。

于 2012-01-25T08:58:15.740 回答
0

关于。你自己的回应。如果您将其用于错误日志记录,并且在刷新流之前编程崩溃,那么您的日志记录有点没用,不是吗?

于 2009-12-09T13:20:31.670 回答