【问题标题】:What are the options for safe use of fstream with many threads多线程安全使用 fstream 的选项有哪些
【发布时间】:2013-04-12 14:05:06
【问题描述】:

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

编辑: 有没有办法以独占模式打开 fstream? 如果您认为 fstream 是在许多线程环境中使用的最差选择,还有哪些其他可能性?

【问题讨论】:

    标签: c++ multithreading fstream


    【解决方案1】:

    互斥锁等同步原语很有帮助。比如引入了std::mutexstd::lock_guard的C++11标准库。

    一种可能性是围绕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,... 具有互斥锁。但是它们的主要结构都是一样的

    【讨论】:

    • 我特别同意这个答案,因为它不允许同时允许多个读者。我想不出任何合理的方式让多个读者安全地同时访问fstreamfstream(通常)被缓冲,因此执行读取操作会改变缓冲区和缓冲区指针。
    • 你是对的。也许我应该忘记 fstream 并应该使用任何其他(Windows)IO,有什么想法吗?
    • 顺便说一句,这里使用指向 fstream 的指针比直接使用 fstream 有什么优势吗?
    • 好的,但是这段代码真的有帮助吗?如果我使用具有相同路径的不同 fstream 创建两个 FstreamWriter 对象会怎样。这些对象中的每一个都有自己的互斥体,因此当有很多线程时,它们可以在完全相同的时间读取。
    • 如果输出是面向行的,那么数据不能以这种方式混合吗?锁只存在于处理链中的单个参数。例如线程#1:out
    【解决方案2】:

    您应该使用低级 IO 库中的锁定机制,而不是使用互斥锁。因此,将文件名传递给您正在实现的流类,并使用文件名来制作您自己的 fstream 对象,但在执行 operator

    构造函数:

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

    操作员

    使用 ::flock(fileDescriptor, LOCK_EX);在 fstream

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-10
      • 2014-06-05
      • 1970-01-01
      • 1970-01-01
      • 2012-06-24
      • 1970-01-01
      • 2015-07-20
      相关资源
      最近更新 更多