有多个线程安全使用fstream的选项有哪些?

时间:2013-04-12 14:05:06

标签: c++ multithreading fstream

我正在创建自己的IO系统,它正在使用fstream。会有很多线程,我的问题是如何保持安全,这意味着允许从一个文件中多次读取但保持写入独占。因此,例如,如果有两个线程想要写入文件,我希望第二个线程等到第一个关闭其fstream。 这里Accessing a single file with multiple threads 有人提议使用TMultiReadExclusiveWriteSynchronizer,但不确定它是否是最佳选择。 我的想法是只保留地图并在打开任何文件之前手动检查,如果文件可以安全打开,如果没有让线程等到文件被释放。

编辑: 有没有办法在独家模式下打开fstream? 如果您认为fstream是最糟糕的选择,那么在许多线程环境中使用什么是其他可能性?

2 个答案:

答案 0 :(得分:2)

同步原语(如互斥)很有帮助。例如,C ++ 11标准库引入了std::mutexstd::lock_guard

一种可能性是围绕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);

然后在各种线程中使用fwriter对象:

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

如果你不使用C ++ 11,有很多替代品,如Boost,Qt,POSIX,Windows-API,......都有互斥。但主要结构在所有这些中都是相同的

答案 1 :(得分:1)

您应该使用低级IO库中的锁定机制,而不是使用互斥锁。因此,传递给您正在实现文件名的流类,并使用文件名来创建自己的fstream对象,但是在运算符的实现中&lt;&lt;使用锁,所以这将始终有效,而不是必需的线程。

构造

打开文件以获取文件描述符, 将描述符传递给fstream构造函数

运营商LT;&LT;:

使用:: flock(fileDescriptor,LOCK_EX);在fstream&lt;&lt;之前,不要忘记用:: flock(fileDecriptor,LOCK_UN)解锁它;