从不同线程写入文件的正确方法(使用Qt c ++)

时间:2012-10-20 11:34:58

标签: c++ multithreading qt locking

我有线程池创建线程,每个线程工作者计算一些工作以及何时完成 它将结果写入文件,每个工作线程只需要写入1个结果文件 现在我的问题是我如何保证不会有任何锁定或丢失写入数据的文件,其中所有线程试图写入单个文件?这种情况的正确策略是什么? mybe将所有结果留在记忆中?或结果的沟渠

我已经使用了QThreadPool框架,我需要找到它的解决方案 我也徘徊,从工作线程写入单个文件,我将不得不使用
单例文件管理器或静态类,这是个好主意吗?对于多线程应用程序?

2 个答案:

答案 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;
};