C++ - 如何让多个线程写入一个文件
C++ - How to have multiple threads write to a file
我目前正在编写一个 C++ 程序,该程序使用线程将字符串写入文件。我正在使用 ofstream 来编写这些字符串,我注意到只有一个线程可以访问该文件。
所以我的问题是:有没有办法在不同的线程中使用 ofstream 来写入同一个文件?
如果可能的话,任何例子都很好。如果没有,请也让我知道,一些解决这个问题的方法会很棒。
我查看了以下 link,但它对我来说并没有真正意义:
Can multiple threads write into a file simultaneously, if all the threads are writing to different locations?
让多个线程写入同一个文件会导致一些严重的问题。您可以尝试使用临界区同步写入过程,例如(使用 OpenMP):
#pragma omp critical [(name)]
{
write_to_file
}
或使用 WinApi:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms686908(v=vs.85).aspx
一种方法是创建一个包装文件的单个对象,然后向需要写入文件的所有对象提供对此包装器对象的引用。在这个包装器 class 中,对文件的写入是同步的,因此一次只有一个写入器可以提交要写入的数据(即,一个写入器将在另一个写入器或同一写入器可以写入之前完成)。例如:
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;
};
使用这些编写器的客户端代码类似于以下内容:
// 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);
使用这种方法,单个对象(SynchronizedFile
类型)管理文件,所有写入都通过该对象进行管理。现在,为了保证只有一个线程可以使用write(const string&)
,一个std::lock_guard
。使用这种锁定机制,SynchronizedFile
的实现类似于:
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;
};
既然写入文件似乎不是你的问题,我把打开和写入留给你去实现,但上面的代码片段显示了同步写入的基本结构。如果您在打开和写入文件时遇到问题,请告诉我,我可以为您解决。
注意:以上片段使用了C++11结构。如果您不能使用 C++11,请告诉我,我们可以考虑使用 C++98(或其他 libraries/APIs)来获得相同的结果。
我目前正在编写一个 C++ 程序,该程序使用线程将字符串写入文件。我正在使用 ofstream 来编写这些字符串,我注意到只有一个线程可以访问该文件。
所以我的问题是:有没有办法在不同的线程中使用 ofstream 来写入同一个文件?
如果可能的话,任何例子都很好。如果没有,请也让我知道,一些解决这个问题的方法会很棒。 我查看了以下 link,但它对我来说并没有真正意义: Can multiple threads write into a file simultaneously, if all the threads are writing to different locations?
让多个线程写入同一个文件会导致一些严重的问题。您可以尝试使用临界区同步写入过程,例如(使用 OpenMP):
#pragma omp critical [(name)]
{
write_to_file
}
或使用 WinApi: https://msdn.microsoft.com/en-us/library/windows/desktop/ms686908(v=vs.85).aspx
一种方法是创建一个包装文件的单个对象,然后向需要写入文件的所有对象提供对此包装器对象的引用。在这个包装器 class 中,对文件的写入是同步的,因此一次只有一个写入器可以提交要写入的数据(即,一个写入器将在另一个写入器或同一写入器可以写入之前完成)。例如:
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;
};
使用这些编写器的客户端代码类似于以下内容:
// 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);
使用这种方法,单个对象(SynchronizedFile
类型)管理文件,所有写入都通过该对象进行管理。现在,为了保证只有一个线程可以使用write(const string&)
,一个std::lock_guard
。使用这种锁定机制,SynchronizedFile
的实现类似于:
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;
};
既然写入文件似乎不是你的问题,我把打开和写入留给你去实现,但上面的代码片段显示了同步写入的基本结构。如果您在打开和写入文件时遇到问题,请告诉我,我可以为您解决。
注意:以上片段使用了C++11结构。如果您不能使用 C++11,请告诉我,我们可以考虑使用 C++98(或其他 libraries/APIs)来获得相同的结果。