我有线程池创建线程,每个线程工作者计算一些工作以及何时完成 它将结果写入文件,每个工作线程只需要写入1个结果文件 现在我的问题是我如何保证不会有任何锁定或丢失写入数据的文件,其中所有线程试图写入单个文件?这种情况的正确策略是什么? mybe将所有结果留在记忆中?或结果的沟渠
我已经使用了QThreadPool框架,我需要找到它的解决方案
我也徘徊,从工作线程写入单个文件,我将不得不使用
单例文件管理器或静态类,这是个好主意吗?对于多线程应用程序?
答案 0 :(得分:5)
因此,您有许多并发线程竞争一个共享资源。这需要某种同步原语,例如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;
}
当然,如果您的代码中有很多地方访问共享资源,最好将它与互斥锁一起封装在某个“访问器”类中,该类将管理对资源的所有状态修改调用。
P.S。如果您不使用C ++ 11编译器,则可以使用boost::mutex
或Qt特定的互斥包装器。关键是你需要与共享资源相关联的一些同步原语。
答案 1 :(得分:2)
正如我所假设的那样,你自己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;
};