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

后端 未结 2 973
自闭症患者
自闭症患者 2021-02-04 17:10

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 acc

相关标签:
2条回答
  • 2021-02-04 17:20

    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

    0 讨论(0)
  • 2021-02-04 17:37

    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.

    0 讨论(0)
提交回复
热议问题