From what I read, the standard output streams are generally not thread safe. I have a C++ application (Windows-based, using Visual Studio 2005) that has a very simple logging function:
void logText(string text)
{
if(g_OutputLogEnabled && g_OutputLog.is_open())
{
string logDate = getDateStamp("%Y-%m-%d %H:%M:%S");
g_OutputLog << "[" << logDate << "]: " << text << endl;
}
cout << text << endl; // Also echo on stdout
}
In this example, g_OutputLog is an ofstream and g_OutputLogEnabled is a boolean.
I’ve been using this small function in my main application with no problem, but I now want to extend its use to some child threads. These threads do work and asynchronously print data as that work is done.
Question: How can I add simple, line-level thread-safety to this routine? All that I really care about is that each line that comes in remains intact in my log. Performance isn’t a concern in this case, but (as always) faster is nicer.
I’m aware I could use third party logging packages, but I want to do it myself so I can learn how it works. My multi-threading knowledge isn’t what it should be, and I’m trying to improve that.
I’ve heard the term critical sections, and I’m somewhat aware of mutexes and semaphores, but which would I use in this case? Is there a clean, simple solution? Thanks in advance for any advice.
Use scoped lock such as:
Or you could use
std::unique_lockif your compiler supports this.How would you implement
scoped_lockif you cannot use Boost and if you don’t havestd::unique_lock?First define
mutexclass:Then define
scoped_lockas:Now you can use them.