【问题标题】:Multithreading with QString使用 QString 进行多线程
【发布时间】:2016-09-06 13:16:12
【问题描述】:

我正在接近多线程世界。 我有一个关于 QString 和多线程应用程序的问题。

我的主要应用类是:

MyGeneralClass{
    public:
    std::vector< QString > hpg_lines;
    .
    .
    .

};

我的多线程类如下所示:

class MyTread:public QThread{
    private:
    QString qstr_;
    MyGeneralClass *gen_;
    .
    .
};

每个线程在其 qstr 对象中写入一些内容(大量字符串),并在线程结束时将其复制到主类的向量 hpg_lines 上。 我可以这样做还是我可能会发生一些数据丢失? 谢谢你的帮助

【问题讨论】:

  • 不确定您是否落入了那个陷阱,但请注意QThread 是线程控制器。它不是线程。因此,最好将线程修改的任何变量以及要在线程中运行的任何代码放入单独的类中。还要注意,如果你想要一个运行线程的 Qt 事件循环(这样你就可以将信号连接到线程中的插槽),你通常不应该继承 QThread,因为没有理由(以及许多不必要的方法你可以拧如果你这样做,事情就会发生)。

标签: c++ multithreading qt


【解决方案1】:

据我所知,std::vector 不是线程安全的(用于读写)。由于您需要同时访问共享数据结构,因此最天真和最简单的解决方案应该是 http://doc.qt.io/qt-5/qmutex.html 。声明一个新的互斥体然后使用:

    your_mutex.lock();
    do your stuff on the data structure;
    your_mutex.unlock();

确保 your_mutex 也是线程之间的相同资源,而不是每个线程都有一个互斥锁。这意味着互斥锁可能应该是全局变量或传递给每个线程。

【讨论】:

  • 从软件工程的角度来看,创建自己的 threadsafe_vector 更有意义,它基本上只是 vector 的包装器,它首先创建 std::lock_guard 以锁定 std::mutex (如果抛出异常,您的版本会中断)。
  • 非常感谢。我向 MyGeneralClass 添加了一个私有对象 QMutex,它可以通过指针 *gen_ 从所有线程访问。每次对向量进行操作时,我都会添加锁定和解锁互斥锁函数。现在我的代码可以正常工作了!
  • @Mike vector 有很多成员函数,将它们全部重新声明是不可行的。我会在需要时添加这些函数,并且通常最终只有 5 或 10 个。或者,您可以公开 vector 并期望调用者不要保留超过锁定的引用,但这可能会出错。
【解决方案2】:

最安全的方法是将结果传递给控制线程,并且该线程可以将结果复制到向量中。这样就不会从多个线程访问向量。在 Qt 中,这可以通过 queued connection 来完成。

【讨论】:

    【解决方案3】:

    当您要将字符串写入 qstr 并添加到向量 hpg_lines 时,请使用 mutex.lock() 和 mutex.unlock() 函数; (mutex 是 Qmutex 类的一个对象)

    例如

    mutex.lock()
        write string to qstr;
        add qstr to hpg_lines;
    mutex.unlock();
    

    这样其他线程将不允许修改qstr或hpg_lines;

    谢谢 萨吉什

    【讨论】:

      猜你喜欢
      • 2023-03-12
      • 2015-09-26
      • 1970-01-01
      • 2016-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多