std::thread Qt 和 QWidget 更新中的安全性

std::thread safety in Qt and QWidget update

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

我读到 Cocos2d-x 无法处理并发调用,因为 API 不包括某些 属性 修改。我没有在 Qt 文档上找到有关线程安全的信息,这里有人说 Qt Widgets 不是线程安全的。实际上 QWidget::update() 是一个 public 槽,那么我应该尝试将所有直接函数调用转换为 update() 以发出信号吗?我想用纯 C++ 进行线程处理,在使用 Qt 时有什么限制?

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

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

Qt 中的信号和槽会在线程边界上工作,只要接收线程(槽)是 运行 事件循环(Qt 线程显然就是这样)。对该线程或信号员的线程没有其他要求。如果您从不同的线程发送信号,Qt 会自动将其排入接收线程的事件队列。

这也可以在设置 signal/slot 连接时通过传递正确的连接类型参数来明确。见 explanation of connection types in Qt doc.

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