I'm working on a multithread c++ application and actually I'm facing the problem of interleaved console output, caused by concurrent thread calls to cout
/cerr
. Note: I can't use boost/QT/other frameworks, but only standard c++.
As a temporary fix I'm using this class: (actually this is a win32 code snippet, that's why the use of CRITICAL_SECTION as temp workaround);
class SyncLogger
{
public:
SyncLogger() { InitializeCriticalSection(&crit); }
~SyncLogger() { DeleteCriticalSection(&crit); }
void print(std::ostringstream &os) {
EnterCriticalSection(&crit);
std::cout << os.str();
os.str(""); // clean stream
LeaveCriticalSection(&crit);
}
private:
CRITICAL_SECTION crit;
};
The usage is the following:
...
ostringstream ss;
ss << "Hello world, I'm a thread!" << endl;
syncLogger.print(ss);
I think this is very ugly, but it seems to work.
Btw thanks to this other question ( Best way to add a "prompt" message to std::cout) I have created the following logging class:
class MyLogger
{
std::ostream & out;
std::string const msg;
public:
MyLogger(std::ostream & o, std::string s)
: out(o)
, msg(std::move(s))
{ }
template <typename T>
std::ostream & operator<<(T const & x)
{
return out << msg << x;
}
};
So, does exist a way to provide built-in locking within the class MyLogger
(using critical section or win32 mutex)?
My best whish is that any thread will be able to print messages in a sync way, simply using
myLog << "thread foo log message" << endl;
and without the need to create an ostringstream
object every time.
Thanks in advance.