Tomáš Zato
Tomáš Zato

Reputation: 53129

Multithreaded filestream

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:

  1. How do I make std::ofstream to only log one data at a time? (remembering other and inserting it AFTER, not in the middle)
  2. How do I check if the file was closed by other thread. (or an error)

Bonus question: Could you solve same problem for std::cout?

Upvotes: 0

Views: 1491

Answers (1)

Collin Dauphinee
Collin Dauphinee

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

Related Questions