c++ - 使用 moveToThread 时是否需要锁定

标签 c++ multithreading qt qthread

我搜索了这个站点和 QT 文档,但找不到以下问题的直接答案:

假设我有一个只有一个插槽的 worker 类:

void Worker::testSlot(){
  //access data and do some calculation
}

现在,如果这个插槽连接到来自其他线程上运行的其他类的信号,并且如果使用排队连接,那么在访问 worker 中的数据之前是否有必要使用锁(QMutexLocker)?我认为不需要,因为 testSlot() 总是在一个线程中执行(移动工作线程的线程),因此它是同步的。即使两个信号同时从不同的线程发出,也没有办法在第一个信号的中途暂停执行插槽并为第二个信号启动。但我不确定这一点。

最佳答案

你 100% 正确。

信息的关键位是通过排队或自动连接发送连接到不同线程中的对象的信号会导致将 QMetaCallEvent 发送到目标对象。它根本不会直接导致任何调用。

在目标对象所在的线程中运行的事件循环将事件传递给对象 - 您可以通过正确覆盖 event 方法并在事件发生时输出调试消息来验证这一点MetaCall 类型。请记住在您的重新实现中调用基类的方法。由于事件循环同步运行,因此它会串行执行调用。因此不需要额外的访问序列化手段。元调用事件是从哪个线程发布的并不重要——线程本身不用于发布,并且事件队列看起来是一样的,无论是从一个线程还是多个线程发布了多个事件。

QObject::event 方法处理QMetaCallEvent 并执行调用。调用可能是对槽、可调用方法、构造函数/析构函数或将在给定对象的线程上下文中执行的仿函数。

关于c++ - 使用 moveToThread 时是否需要锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22803283/

相关文章:

c++ - 我的线程函数不会停止我想要的线程

linux - 如何避免在 .so 文件名中包含版本号

c++ - 将参数定义为未指定的模板类型

c++ - 数组中的数据自动更改

c++ - 如何交换两个 std::atomic 变量?

c - 如果我创建一个原子变量,线程之间对该变量的所有操作都是原子的吗?

c++ - 将派生自抽象基类的对象与映射存储在基类指针的 vector 数组中

c++ - Boost threads - 处理线程中断的安全/保证方式

python - 调用 setParent 时 QMenu 显示不正确

c++ - 如何打印 QGraphicsView 的内容