rank1
rank1

Reputation: 1038

What are the options for safe use of fstream with many threads

I am creating my own IOsystem, which is using fstream. There will be many threads and my question is how can I keep it safe which means to allow multiple read from one file but keep writing exclusive. So for example if there are two threads that want to write to file I want the second one to wait until first one close its fstream. Here Accessing a single file with multiple threads it was proposed to use TMultiReadExclusiveWriteSynchronizer but it am not sure if it's the best option. One my idea is to just keep the map and check it manually before opening any file if the file can be safely open, if not make the thread wait until the file is released.

EDIT: And is there any way to open fstream in exclusive mode? If You think that fstream is the worst option use in many threads enviroments what are other possibilities ?

Upvotes: 2

Views: 5389

Answers (2)

doc_ds
doc_ds

Reputation: 241

Instead of using mutexes, you should use locking mechanism from the low-level IO library. So, pass to the the stream class you're implementing the file name, and use the file name to make your own fstream object, but in the implementation of the operator<< use the lock, so this will always work, not necessary thread only.

Constructor:

open the file to get the file descriptor, pass the descriptor to the fstream constructor

operator<<:

use the ::flock(fileDescriptor, LOCK_EX); before fstream<<, and do not forget to unlock it with the ::flock(fileDecriptor, LOCK_UN);

Upvotes: 1

masoud
masoud

Reputation: 56479

Synchronization primitives such as mutex are helpful. For example C++11 standard library introduced std::mutex and std::lock_guard.

One possibility is to write a thread-safe wrapper around operator<< :

class FStreamWriter
{
    std::fstream *f;
    std::mutex mtx;
public:
    FStreamWriter(std::fstream *f) : f(f) {}

    template <typename T>
    FStreamWriter &operator<<(const T &x)
    {
        std::lock_guard<std::mutex> lock(mtx); // <- Mutex to make it safe-thread
        (*f) << x;
        return *this;
    }
   // ...
};

fstream file("my_file.txt");

// ...

FStreamWriter fwriter(&file);

and then use fwriter object in various threads:

fwriter << "Hello" << 1 << 2 << 3;

If you doesn't use C++11, there is many alternatives such as Boost, Qt, POSIX, Windows-API, ... which have mutex. But the main structure is same in all of them

Upvotes: 2

Related Questions