我有创建线程的线程池,每个线程工作者计算一些工作,完成后将结果写入文件,只有 1 个结果文件,每个工作者线程需要写入。
现在我的问题是我如何保证不会有任何锁或丢失写入数据到分配线程试图写入单个文件的文件?这种情况的正确策略是什么?
mybe 将所有结果保存在内存中?或结果
我已经在使用 QThreadPool 框架,我需要找到解决方案。
我也徘徊,是否从工作线程写入单个文件,我将不得不使用
单例文件管理器或静态类,这是个好主意吗?对于多线程应用程序?
我有创建线程的线程池,每个线程工作者计算一些工作,完成后将结果写入文件,只有 1 个结果文件,每个工作者线程需要写入。
现在我的问题是我如何保证不会有任何锁或丢失写入数据到分配线程试图写入单个文件的文件?这种情况的正确策略是什么?
mybe 将所有结果保存在内存中?或结果
我已经在使用 QThreadPool 框架,我需要找到解决方案。
我也徘徊,是否从工作线程写入单个文件,我将不得不使用
单例文件管理器或静态类,这是个好主意吗?对于多线程应用程序?
因此,您有许多并发线程竞争一个共享资源。这需要某种同步原语,例如mutex。
这是(非 Qt 特定的)代码,展示了 10 个线程同时写入单个文件。附带说明一下,C++11 引入了很多好东西,比如std::mutex
(而且std::thread
,这样可以帮助消除一些特定于 Qt 的线程代码)。
#include <fstream>
#include <mutex>
#include <thread>
#include <vector>
std::mutex m;
std::ofstream file;
int main() {
file.open("file.txt");
std::vector<std::thread> workers;
for (int i = 0; i < 10; ++i) {
workers.push_back(std::thread([=i] {
for (int j = 0; j < 10; ++j) {
std::lock_guard<std::mutex> lock(m);
file << "thread " << i << ": " << j << endl;
}
}));
}
for (auto& worker : workers) {
worker.join();
}
file.close();
return 0;
}
当然,如果您的代码中有很多地方访问共享资源,最好将它与互斥锁一起封装在一些“访问器”类中,该类将管理对资源的所有状态修改调用。
PS 如果您不在 C++11 编译器上,则可以使用boost::mutex
或 Qt 特定的互斥体包装器。关键是您需要一些与共享资源关联的同步原语。
正如我假设的那样,您创建自己的Runnable
,源自QRunnable
您可以在构建Runnable
类时传递一些上下文信息。例如,您需要通过设备写入和mutex
锁定设备。
class Runnable: public QRunnable
{
public:
Runnable(QIOdevice* device, QMutex* mutex):_d(device), _m(mutex){}
void run()
{
saveInFile();
}
private:
void saveInFile()
{
QMutexLocker lock(_m);
//now only one thread can write to file in the same moment of time
device->write(...);
}
QIOdevice* _d;
QMutex* _m;
};