Re: Thread save access to cout?
Hi,
Henryk wrote:
Under linux with libstdc++.so.6 is writing to cout thread save or do I
need to make it thread safe by some kind of wrapper?
most C++ runtime implementations are thread safe to some degree if you
use the platform specific compiler switch for multi-threading. However,
this won't help you in any way. See below.
Would something like this do:
inline std::ostream &Wrapper::cout() {
Lock lock(mutex);
return std::cout;
}
In no way.
You lock, then you create a reference to std::cout, then you unlock and
finally you dereference the reference and do your output.
Wrapper::cout() << "print something" << "print more" << std::endl;
How long does the scoped lock protect the access to std::cout? The
mutex is released within lock's destructor, which is called after the
return statement.
Exactly.
I tested it in an VM environment and it worked as far as I visually
checked the output. But does it work for sure?
It never worked and you did not need it.
You will never address the problem with a general wrapper. The first
question is: what is your unit of work? Is <<"print something" a unit of
work and <<"print more" another one and in between another thread might
do it's output. Or is the entire expression your unit of work? Of
course, for both purposes you might write a wrapper, but both
implementation will have significant drawbacks. In any case you need to
implement your own virtual output stream.
The first alternative obviously does not hit the nail on the head,
because one logical set of outputs might be intercepted by content from
other threads.
The second way blocks the entire output stream until your returned
wrapper instance goes out of scope. Depending on your application code
this may be after the statement (as intended) at some other point or
even never resulting in a deadlock. Furthermore you will always lock the
output while subexpressions of your statement are evaluated. So if you
call a function in your output statement that retrieves the output
information, then it is evaluated in synchronized context. Again, this
is obviously not what you want.
You won't come around to redesign your output statements in your
application if you want to provide reasonable thread-safety.
Marcel