C++ - How to have multiple threads write to a file

17,655

Solution 1

One approach is to create a single object that wraps the file and then provide a reference to this wrapper object to all objects that need to write to the file. Within this wrapper class, writing to the file is synchronized so that only one writer can submit data to be written at a time (i.e., one writer will complete before another, or the same writer, can write). For example:

class SynchronizedFile {
public:
    SynchronizedFile (const string& path) : _path(path) {
        // Open file for writing...
    }

    void write (const string& dataToWrite) {
        // Write to the file in a synchronized manner (described below)...
    }

private:
    string _path;
};

class Writer {
public:
    Writer (std::shared_ptr<SynchronizedFile> sf) : _sf(sf) {}

    void someFunctionThatWritesToFile () {
        // Do some work...
        _sf->write("Some data to write...");
    }
private:
    std::shared_ptr<SynchronizedFile> _sf;
};

The client code that uses these writers would resemble the following:

// Create the synchronized file
auto synchronizedFile = std::make_shared<SynchronizedFile>("some/file.txt");

// Create the writers using the same synchronized file
Writer writer1(synchronizedFile);
Writer writer2(synchronizedFile);

Using this approach, a single object (of type SynchronizedFile) manages the file and all writing is managed through this object. Now, in order to ensure that only one thread can use the write(const string&), a std::lock_guard. Using this locking mechanism, the implementation for the SynchronizedFile would resemble:

class SynchronizedFile {
public:
    SynchronizedFile (const string& path) : _path(path) {
        // Open file for writing...
    }

    void write (const string& dataToWrite) {
        // Ensure that only one thread can execute at a time
        std::lock_guard<std::mutex> lock(_writerMutex);

        // Write to the file...
    }

private:
    string _path;
    std::mutex _writerMutex;
};

Since it appears as though writing to a file is not your issue, I have left the opening and writing to you to implement, but the above snippet shows the basic structure for synchronizing the writing. If you have issues opening and writing to the file, let me know and I can flush that out for you.

Note: The above snippets use C++11 structures. If you cannot use C++11, let me know and we can look at using C++98 (or other libraries/APIs) to achieve the same results.

Solution 2

Having multiple threads to write to the same file can lead to some serious troubles. You can try synchronizing the process of writing, by using critical section, for example(using OpenMP):

#pragma omp critical [(name)]
{
   write_to_file
}

or using WinApi: https://msdn.microsoft.com/en-us/library/windows/desktop/ms686908(v=vs.85).aspx

Share:
17,655
Flare Cat
Author by

Flare Cat

I am a 15 year old student, that enjoys programming in C++. Youtube: https://www.youtube.com/channel/UC5W7n0gefWSWXBqefZPrgLQ/

Updated on October 16, 2022

Comments

  • Flare Cat
    Flare Cat over 1 year

    I am currently writing a c++ program that uses threads to write strings to a file. I am using ofstream to write these strings, and I noticed that only one of the threads has access to the file.

    So my question: Is there any way to use ofstream in different threads to write to the same file?

    If it is possible, any examples would be great. If not, please let me know that as well, and some ways to get around this would be great. I have looked at the following link, except it didn't really make sense to me: Can multiple threads write into a file simultaneously, if all the threads are writing to different locations?

  • user3792685
    user3792685 about 4 years
    Here i don't see any threads or am I missing something? like starting write or writer class function in different threads.
  • Justin Albano
    Justin Albano about 4 years
    @user3792685 Correct. The above does not include the threads themselves. Instead, the SynchronizedFile class simply shows how a file can be wrapped so that it can be used by multiple threads without resulting in thread contention. The task of injecting the SynchronizedFile objects into separate threads is left out for clarity.