简体   繁体   English

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

[英]right way to write to file from different threads (using Qt c++ )

i have thread pool that create threads each thread worker calculate some work and when it done it writes the result to file , there is only 1 result file , that each worker thread needs to write to . 我有创建线程的线程池,每个线程工作人员都要计算一些工作,完成后它将结果写入文件,每个工作线程都需要向其中写入一个结果文件。
now my question is how i guarantee that there wouldn't be any locks or missing write data to the file where allot of threads trying to write to single file ? 现在我的问题是我如何保证不会有任何锁或丢失向试图分配到单个文件的线程分配的文件写入数据? what is the right strategy for such scenario? 这种情况下正确的策略是什么?
mybe keep all result in memory ? 我要把所有结果保存在内存中吗? or chanks of results 或结果

im using already the QThreadPool framework , and i need to find solution with it. 我已经使用了QThreadPool框架,我需要用它找到解决方案。
also i wander , does writing to single file from worker threads , i will have to use 我也徘徊,确实从工作线程写入单个文件,我将不得不使用
singleton file manager or static class , is it good idea? 单例文件管理器或静态类,这是个好主意吗? for multithreaded app ? 对于多线程应用程序?

So you have many concurrent threads competing for one shared resource. 因此,您有许多并发线程争用一种共享资源。 That begs a synchronization primitive of some sort, for example a mutex . 这就产生了某种同步原语,例如互斥体

Here's (non-Qt specific) code showcasing 10 threads simultaneously writing to a single file. 下面的代码(非Qt专用)展示了10个线程同时写入一个文件。 On a side note, C++11 introduced a lot of goodies like std::mutex (and std::thread too, so that can help eliminate some Qt-specific threading code). 附带说明一下,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;
}

Of course, if you have a lot of places in your code accessing the shared resource, it's better to encapsulate it, along with the mutex, in some "accessor" class that would manage all state-modifying calls to the resource. 当然,如果代码中有很多地方可以访问共享资源,则最好将它与互斥锁一起封装在一些“访问器”类中,该类可以管理对资源的所有状态修改调用。

PS If you're not on C++11 compiler, you can use boost::mutex or Qt-specific mutex wrapper. PS如果您不在C ++ 11编译器上,则可以使用boost::mutex或Qt特定的互斥体包装器。 The key thing is that you need some synchronization primitive associated with the shared resource. 关键是您需要一些与共享资源关联的同步原语。

As I assume, you crate your own Runnable , deriving from QRunnable 正如我所假设的,您创建了自己的Runnable ,它源自QRunnable

You can pass some context information when constructing your Runnable class. 在构造Runnable类时,您可以传递一些上下文信息。 You need to pass device to write in and mutex to lock device, for example. 例如,您需要传递设备以写入并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;
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM