【问题标题】:right way to write to file from different threads (using Qt c++ )从不同线程写入文件的正确方法(使用 Qt c++)
【发布时间】:2012-10-20 11:34:57
【问题描述】:

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

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

【问题讨论】:

标签: c++ multithreading qt locking


【解决方案1】:

因此,您有许多并发线程竞争一个共享资源。这需要某种同步原语,例如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;
}

当然,如果您的代码中有很多地方访问共享资源,最好将其与互斥锁一起封装在某个“访问器”类中,该类将管理对资源的所有状态修改调用。

附:如果您不在 C++11 编译器上,则可以使用 boost::mutex 或特定于 Qt 的互斥体包装器。关键是您需要与共享资源关联的一些同步原语。

【讨论】:

    【解决方案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;
    };
    

    【讨论】:

    • 写入完成后不要忘记解锁互斥锁。
    • @Pedro, QMutexLockerstd::lock_guard 类似。它在超出范围后解锁互斥锁。它实现了 RAII 风格的锁定机制
    猜你喜欢
    • 1970-01-01
    • 2014-01-15
    • 1970-01-01
    • 2013-07-16
    • 2016-07-19
    • 2012-01-05
    • 1970-01-01
    • 2022-01-17
    • 2012-12-02
    相关资源
    最近更新 更多