1

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

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

4

2 回答 2

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 等,它们都具有互斥锁。但是它们的主要结构都是一样的

于 2013-04-12T14:27:13.713 回答
1

您应该使用低级 IO 库中的锁定机制,而不是使用互斥锁。因此,将文件名传递给您正在实现的流类,并使用文件名来制作您自己的 fstream 对象,但在执行 operator<< 时使用锁,所以这将始终有效,不需要线程只要。

构造函数:

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

运算符<<:

使用 ::flock(fileDescriptor, LOCK_EX); 在 fstream<< 之前,不要忘记使用 ::flock(fileDecriptor, LOCK_UN);

于 2014-03-03T12:17:40.457 回答