Threadsafe Protocol

I want to implement a simple class for logging from multiple threads. The idea is that every object that wants to record material gets an ostream object that can write messages using regular operators. The desired behavior is that messages are added to the log when streaming. Thus, messages will not be interrupted by messages from other threads. I want to avoid using a temporary stringstream to store the message, as this would make most messages at least two parents. As I see it, the standard way to achieve this would be to implement your own stream buffer, but it seems very cumbersome and error prone. Is there an easier way to do this? If not, do you know a good article / guide / user guide for streambufs?

Thanks in advance,

Space_c0wbo0y

UPDATE:

Since this works, I added my own answer.

+7
c ++ logging streambuf
source share
4 answers

So, I took a look at Boost.IOstreams and this is what I came up with:

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 can be used to create a stream buffer (see stream_buffer-template ). Each thread will receive its own instance of TestSink , but all TestSinks will be written to the same log. TestSink used as follows:

 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; 

The important fact here is that TestSink.write is called only when the stream stream ( std::endl or std::flush ) or when the internal buffer of the stream_buffer instance stream_buffer full (the default buffer size cannot hold 40,000 characters, so I initialize it to 50,000 ) In this program, TestSink.write is called exactly once (the output is too long to publish here). This way I can write logmessage using standard formatted I / O stream without any temporary variables and make sure that the message is sent to the log in one fragment when I clear the stream.

I will leave the question open one more day if there are different suggestions / problems that I have not considered.

+1
source share

Take a look at log4cpp ; they support multithreading. It can save your time.

+5
source share

You think log4cpp is too heavy and you are using Boost.IOStreams instead? BUT?

You might want to consider logog . It is thread safe for POSIX, Win32 and Win64.

+1
source share

Re. your own answer. If you use this to log errors and you fail before flushing the stream, then you are logging a little uselessly, right?

0
source share

All Articles