Reputation: 53129
I'm creating a client application that connects to a server and, besides other features, logs server chat into a file, so that rule violations may be punished later.
Unfortunatelly, it became necessary to have (at least) two threads in the application: receiver loop and sender loop - timing precesion is required by the server. This means, I need thread safe solution for logging data to a file.
This is what may happen, if threads send log information at the (as much as possible) same time:
logfile.txt:
chat: Hello my name is Duke
chat: Hell[WARNING]: Hacker detectedo my name is John
You can see one sentence injected into another. I don't want this to ever happen. Same happens to my std::cout
output, but that is not so critical.
Questions:
std::ofstream
to only log one data at a time? (remembering other and inserting it AFTER, not in the middle)Bonus question:
Could you solve same problem for std::cout
?
Upvotes: 0
Views: 1491
Reputation: 13973
Standard streams have no thread safety guarantees. The only way to safely accomplish what you're trying to do is to serialize access to the stream.
The easiest solution is to wrap any statement involving the stream in a mutex.
{
std::lock_guard<std::mutex> locked(gCoutMutex);
std::cout << "This is a message" << std::endl;
}
A more correct approach, especially for a logger, is to have a logging thread with a message queue. When another thread wants to log, it just posts a message to the queue, and the logging thread will go through the queue and write everything to disk.
Upvotes: 4