【问题标题】:std::thread safety in Qt and QWidget update [duplicate]Qt 和 QWidget 更新中的 std::thread 安全 [重复]
【发布时间】:2015-12-26 22:43:17
【问题描述】:

我有一个在 std::thread 上运行的模拟,它有规律的睡眠周期,并且在每个周期结束时 QWidget::update() 在我的自定义 QGraphicsObject 上被调用。它大部分时间都在工作,有时在 1024^2 网格上计算 100k 次迭代,但有时 QGraphicsView 不再自我更新。我怀疑存在多线程通信问题。

我读到过,例如 Cocos2d-x 不能处理它的 API 中的并发调用,除了一些属性修改。我没有在 Qt 文档上找到有关线程安全的信息,这里有些人说 Qt Widgets 不是线程安全的。实际上 QWidget::update() 是一个公共插槽,所以我应该尝试将所有直接函数调用转换为 update() 以发出信号吗?我想用纯 C++ 做我的线程,在使用 Qt 时有什么限制?

(如果像这样使用 std::thread 应该是安全的,我将专门针对该问题提出一个新问题)

【问题讨论】:

  • 创建问题最难的部分是找到可能的重复项 :( 这个问题是 4 年前提出的,有 5383 次查看。在查询“qt thread-safety”后我仍然无法在谷歌上找到它“即使它的标签中有“qt”和“thread-safety”......嗯

标签: c++ multithreading qt thread-safety qwidget


【解决方案1】:

在 Qt 中,仅在 GUI(通常是主)线程中调用 GUI 对象的方法非常重要。

只要接收线程(插槽)正在运行事件循环(正如 Qt 线程显然所做的那样),Qt 中的信号和插槽就可以在线程边界上工作。此线程或信号器线程没有其他要求。如果您从不同的线程发送信号,Qt 会自动将其排入接收线程的事件队列。

这也可以在设置信号/插槽连接时通过传递正确的连接类型参数来明确。请参阅explanation of connection types in Qt doc

所以答案是肯定的,你不能可靠地从其他线程调用任何小部件方法,是的,信号/插槽机制是在从工作线程触发 GUI 操作时确保线程安全的适当方法。

【讨论】:

  • 是的,它就像一个魅力:信号:void scheduleUpdate(); ////////////// public: void requestUpdate() { 发出 scheduleUpdate(); } /////////////// 公共槽:void executeUpdate() { update();通过从 std::thread 调用 scheduleUpdate ,它以这种方式将执行交给 QObject 的线程。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-11
  • 1970-01-01
  • 1970-01-01
  • 2017-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多