'Does atomizing a stream protect data in a thread through member functions

So based on this scenario:

#include <fstream>
#include <thread>
#include <string>

// Atomize this
std::ofstream f;

void func() 
{
  std::queue<std::string> sq;
  std::string s;
  for (volatile int i = 0; i < 10 || !f.eof(); i++) {
    // Will s get corrupted?
    std::getline(f, s);
    sq.push(s);
  }
}

int main()
{
  f.open("somefile.txt");
  std::vector<std::thread> threads;
  for (int i = 0; i < 10; i++) {
    threads.push_back(std::thread(func));
  }
}

I'll be calling getline inside of a thread, which (I assume) works no different than a loop that increments the file pointer into a string until a delimiter. What is the appropriate way of securing the file pointer such that getline doesnt collect garbage data. Point B: I just set up a mutex to lock it while getline is being run.

I read that atomic type variables cannot be written/read at the same time, but I'm unsure if this works in a member function as well. Does it lock from reading/writing until the getline method terminates? Or will it (un)lock as getline loops *f;

Of course I can mutex this, I am just curious if streams are threadsafe in this scenario.



Solution 1:[1]

Using stream objects in multiple threads without explicit synchronization generally introduces data races. (The standard streams std::cout and companions are an exception under certain conditions.)

If by "atomize" you mean something like

std::atomic<std::ofstream> f;

that is not possible. std::atomic works only with trivially copyable types (or std::shared_ptr/std::weak_ptr).

You need to use a mutex.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 user17732522