Qt 4.5 - 发出信号是函数调用还是线程,它会阻塞吗?

Ext*_*kun 36 qt qt4

我不确定Qt 4.5中信号/插槽机制的性质.发出信号时,它是阻塞函数调用还是线程?说这个

emit GrabLatestData();

// proceed with latest data
Run Code Online (Sandbox Code Playgroud)

在继续下一行之前,是否会解决所有信号/槽链?

laa*_*lto 47

这取决于.从文档:

发出信号时,通常会立即执行与其连接的插槽,就像正常的函数调用一样.发生这种情况时,信号和插槽机制完全独立于任何GUI事件循环.emit所有插槽返回后,将在语句后执行代码.使用排队连接时情况略有不同; 在这种情况下,emit关键字后面的代码将立即继续,并且插槽将在稍后执行.

因此在正常情况下,它将是同步和阻塞的,并且对于排队连接,它将是异步和非阻塞的.

  • 另请注意,默认情况下:同一线程中对象之间的连接是直接(同步),不同线程中对象之间的连接排队.如果你认为这是非常合乎逻辑的. (10认同)

小智 27

最大的问题是你无法知道.也就是说,如果你从班级的角度来看.当你发射时,你不知道会发生什么:

  • 如果没有人连接到信号,则没有任何反应
  • 如果使用除Qt :: QueuedConnection之外的任何类型连接同一线程中的某个人,则该调用将被阻止
  • 如果使用Qt :: QueuedConnection连接同一线程中的某个人,则该调用将是非阻塞的
  • 如果来自不同线程的某人使用Qt :: DirectConnection连接(当你这样做时要非常小心!)或Qt :: BlockingQueuedConnection,则调用将被阻塞
  • 如果使用Qt :: AutoConnection或Qt :: QueuedConnection连接来自不同线程的某个人,则该呼叫将是非阻塞的

如果多个对象连接到信号会发生什么会变得更加困难.在这种情况下,某些插槽可能已运行而其他插槽仍在排队.顺便说一句,没有涉及非阻塞连接的线程.只有一个事件会在接收对象的线程的事件循环中发布.


Rob*_*ght 9

拉尔托的答案是正确的.还有一点:如果你的所有QObject都属于同一个线程并且你没有手动指定排队连接,那么连接到信号的插槽的执行同步发生 - 所有处理都将在'emit'之后的下一行之前完成'声明.由于这是最常见的情况,因此您的问题的答案通常是"是".

跨多个线程的信号和插槽的文档可能对您有所帮助.