I have a multi-threaded application, which heavily uses std::cout
for logging without any locking. In such a case, how can I easily add lock mechanism to make std::cout
thread-safe?
I don't want to search for each occurrence of std::cout
and add a line of locking code. That is too tedious.
Any better practice?
In addition to synchronisation this solution provides information about the thread from which the log was written.
DISCLAIMER: It's quite a naive way of syncing the logs, however it might be applicable for some small use cases for debugging.
This can be used like this.
And it will give log output
I guess you could implement your own class which wraps
cout
and associates a mutex with it. Theoperator <<
of that new class would do three things:<<
for the wrapped stream and the passed argumentThis different class would keep the lock and delegate operator
<<
to the wrapped stream. The destructor of that second class would eventually destroy the lock and release the mutex.So any output you write as a single statement, i.e. as a single sequence of
<<
invocations, will be printed atomically as long as all your output goes through that object with the same mutex.Let's call the two classes
synchronized_ostream
andlocked_ostream
. Ifsync_cout
is an instance ofsynchronized_ostream
which wrapsstd::cout
, then the sequencewould result in the following actions:
synchronized_ostream::operator<<
would aquire the locksynchronized_ostream::operator<<
would delegate the printing of "Hello, " tocout
operator<<(std::ostream&, const char*)
would print "Hello, "synchronized_ostream::operator<<
would construct alocked_ostream
and pass the lock to thatlocked_ostream::operator<<
would delegate the printing ofname
tocout
operator<<(std::ostream&, std::string)
would print the namecout
happens for the exclamation point and the endline manipulatorlocked_ostream
temporary gets destructed, the lock is releasedAlong the lines of the answer suggested by Conchylicultor, but without inheriting from
std::ostringstream
:EDIT: Fixed return type for the overloaded operator and added overload for
std::endl
.EDIT 1: I have extended this into a simple header-only library for logging / debugging multi-threaded programs.
Output:
Since
C++20
, you can usestd::osyncstream
wrapper:http://en.cppreference.com/w/cpp/io/basic_osyncstream
I know its an old question, but it helped me a lot with my problem. I created an utility class based on this post answers and I'd like to share my result.
Considering we use C++11 or latter C++ versions, this class provides print and println functions to compose strings before calling the standard output stream and avoid concurrency problems. These are variadic functions which use templates to print different data types.
You can check its use in a producer-consumer problem on my github: https://github.com/eloiluiz/threadsBar
So, here is my code:
For fast debugging c++11 applications and avoid interleaved output I just write small functions like these:
I use these types of functions for outputs and if numeric values are needed I just use something like this:
This is easy and works fine to me, but I don't really know if it is technically correct. So I would be glad to hear your opinions.
Well, I didn't read this:
I'm sorry. However I hope it helps somebody.