• Advertisement
Sign in to follow this  

Boost.Iostreams and multiple threads

This topic is 3226 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've written a logging system based on Boost.Iostreams (I wanted to add date/time information and other stuff to log messages automatically, so I wrote a sink class which I use with boost::iostreams::stream_buffer) but there's a problem with multiple threads trying to access the stream at once. My sink class looks like this:
class log_sink
    std::string filename_;
    std::ofstream outs_;

    typedef char char_type;
    typedef io::sink_tag category;

    log_sink(std::string const &filename);
    log_sink(log_sink const &copy);

    std::streamsize write(const char* s, std::streamsize n);

log_sink::log_sink(std::string const &filename)
    : filename_(filename)

log_sink::log_sink(log_sink const &copy)
    : filename_(copy._filename)

std::streamsize log_sink::write(const char *s, std::streamsize n)
    boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();

    boost::lock_guard<boost::mutex> lock(mutex);
    outs_ << now << " : ";
    outs_.write(s, n);

    return n;
I've then just got a global ostream, which I use like so:
boost::iostreams::stream_buffer<log_sink> debug_buffer;
std::ostream debug(&debug_buffer);

// ...

debug << "some stuff to write to the file" << std::endl;
Now, notice I use a boost::lock_guard<> in an attempt to prevent multiple threads from writing to the file at once. However, I think the problem is that the s pointer that is passed to the write function is pointing to a buffer that's shared between threads, so the lock doesn't really do much. I've had this problem for a while, and I never really bothered to look into it too much. But then I saw the recent Simple STL Logging article and I thought it might have had a solution. Unfortunately, the author basically got around the multi-threading problem by wrapping the whole "log << stuff" thing in a mutex, like this:
boost::mutex::scoped_lock lock(CLogger::log_mutex);
debug << "some stuff to write to the file" << std::endl;
Which I thought was a bit intrusive. I was thinking one way to do it would be to put my global stream object into thread-local storage and then sort out the multi-threading stuff inside my write function, pretty much like it already does. Is there a better way? This is really stretching my knowledge of Boost/SC++L :-)

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement