Qt中是否需要互斥锁,如果不同的线程正在调用另一个不同线程的相同信号?

时间:2017-11-22 12:25:34

标签: c++ multithreading qt signals-slots qt-signals

TYPE2 INTEGER GENERATED ALWAYS AS (CASE WHEN TYPE = 0 THEN ID ELSE TYPE END) should work 只有一个名为class A的对象,并且它位于一个单独的线程上(例如" TCP"):

objectA

注意:我认为connect(&objectA, SIGNAL(MySignal()), &objectA, SLOT(MySlot())); 会照顾Qt::AutoConnection还是QueuedConnection。任何类型的我都可以,这样可以更安全。

现在,如果B(说"处理器")& C(比如" Utility")是不同的线程,它们自己调用DirectConnection
MySignal()中,MySlot()的一些数据正在写入。

问题
我是否需要使用互斥锁来保护objectA的数据? OR
A a;会自动排队,因此MySignal()会被顺序调用吗?

用例:目前我有一个TCP线程,用于向/从服务器发送/接收数据。有时,2个线程可以同时发送数据。由于采用多处理器架构,它现在很可能在一天内以完美的并行方式运行2个线程。

4 个答案:

答案 0 :(得分:1)

假设已在主线程上创建了这些线程,并且默认情况下connect使用Qt::AutoConnection并且文档说:

  

(默认)如果接收器位于发出信号的线程中,则使用Qt::DirectConnection。否则,使用Qt::QueuedConnection。连接类型在发出信号时确定。

当线程发出信号时,由于发送者(在QThread::run()中运行的代码)和接收者(创建QThread对象本身的线程)是不同的线程,{{1} } 用来。那就是:

  

当控制返回到接收者线程的事件循环时,将调用该槽。插槽在接收器的线程中执行。

因此所有Qt::QueuedConnection将在主线程上顺序执行。

更新

你有点改变了你的问题!通常,以下连接意味着:MySlot可以在任何线程(即您调用MySignal的线程)中发出,但是 emit MySignal()仅在MySlot所属的线程中调用(即线程关联)。如果这些线程相同,则同步执行插槽。

objectA

答案 1 :(得分:1)

如果执行插槽的对象与执行emit的对象位于不同的线程中,则调用不是顺序的。 emit不会阻止。因此,如果您在emit之后访问发送对象可能正在写入的数据,则需要将该访问与互斥锁同步,或使用阻塞连接(这意味着您强制执行顺序执行,这意味着emit将一直阻止,直到插槽返回。)

因此,如果emit发生在另一个线程上,并且您希望它阻止,请使用阻塞连接。如果您不希望emit阻止,请使用互斥锁来保护数据。如果emit发生在同一个帖子上,那么无论如何它都将成为阻止连接。

但是,如果emit发生在多个线程中,那么您总是需要一个互斥锁。

答案 2 :(得分:0)

  

我是否需要互斥锁定来保护A a的数据;?

如果您在a的事件循环所在的线程之外访问a的数据,是的,您确实需要锁定。

答案 3 :(得分:0)

你的设计中有一些可疑的东西。

通常,信号为protected,仅从该对象的线程中运行的代码发出。更传统的设计会让对象B和C发出他们自己的信号,然后将这些信号连接到objectA的插槽。

虽然你所拥有的可能工作,但很难推理,而且它可能是审视你的设计的好时机,之后它变得太纠结而无法理解其中发生的事情线程。