使用 moveToThread 时是否需要锁定
Is locking necessary when using moveToThread
我搜索了这个网站和QT文档,但找不到并直接回答以下问题:
假设我有一个只有一个插槽的工人类:
void Worker::testSlot(){
//access data and do some calculation
}
现在,如果此插槽连接到来自其他线程上运行的其他类的信号,并且如果使用排队连接,则在访问worker中的数据之前是否有必要使用锁定(QMutexLocker)?我认为不需要它,因为 testSlot() 总是在一个线程(工人在其中移动的线程)中执行,因此它是同步的。即使两个信号同时从不同的线程发出,也没有办法暂停第一个信号的中途执行插槽,而第二个信号则开始执行。但我不确定这一点。
你是 100% 正确的。
信息的关键位是,通过排队或自动连接发射连接到不同线程中的对象的信号会导致向目标对象发布QMetaCallEvent
。它根本不直接导致任何调用。
在目标对象所在的线程中运行的事件循环将事件传递给对象 - 您可以通过正确重写 event
方法并在事件具有 MetaCall
类型时输出调试消息来验证这一点。请记住在重新实现中调用基类的方法。由于事件循环同步运行,因此它会串行执行调用。因此,不需要额外的序列化访问手段。元调用事件是从哪个线程发布的并不重要 - 线程本身不用于发布,无论从一个线程还是多个线程发布多个事件,事件队列看起来都是一样的。
它是处理QMetaCallEvent
和执行调用的QObject::event
方法。调用可以是槽、可调用方法、构造函数/析构函数或要在给定对象的线程上下文中执行的函子。
相关文章:
- 如何检查线程是否锁定
- C++ 11 中的锁定是否保证访问数据的新鲜度?
- 同一互斥锁顺序上的锁定和解锁是否一致?
- 共享内存的升压容器是否实现锁定?
- 获取大小时是否必须锁定 std::queue?
- 我是否需要在 OpenSSL 1.1.0+ 中使用加密锁定函数来实现线程安全?
- 确定 SQLite 数据库是否已锁定
- 是否有必要锁定
- 锁定的互斥锁是否保护condition_variable和数据?
- C 删除对象,是否锁定
- 托管语言是否锁定本机库的刷新和重新加载变量?
- 是否可以锁定应用程序中常见控件使用的内存?
- 如何判断虚拟内存页是否已锁定
- 如何测试文件是否被锁定和/或只读而不打开?
- 如何判断当前过程是否已经锁定文件
- 我是否必须锁定我刚刚枚举的向量,或者我只在更改它时才这样做?
- 通知线程是否始终需要在修改期间锁定共享数据
- 如果其对象在多个线程中运行,我们是否需要锁定类成员功能
- 我的双重检查锁定模式实现是否正确?
- boost中是否有允许写偏锁定的功能