0

同时从多个线程调用小部件的信号函数是否安全?当多个线程同时调用某个小部件的信号时,Qt 会使用某种内部互斥体来提供其自身数据结构的安全性吗?

据我了解,这是安全的,同时调用一个信号函数会导致 N 个连续调用一个连接的信号。

我对么?

PS调用信号函数的线程是用boost创建的。我认为,这对于这个问题并不重要。我不能使用其他线程,因为这些线程不仅与 GUI 相关,而且它们服务于程序的许多部分。

4

3 回答 3

1

简而言之,您不调用信号,而是发出信号。然后 Qt 在内部处理信号连接到的任何插槽的触发。

根据连接类型,发出信号并让它触发插槽可能是线程安全的,也可能不是线程安全的。

阅读此处了解更多信息。

而且我认为boost创建的线程会是一个问题——信号/槽机制依赖于QThread和QObject的基础设施。如果您可以使用 QThread 而不是 boost 线程,它可能会更好更简单。

于 2013-08-28T02:01:17.887 回答
0

如果您将使用 QThreads,则完全没有问题,因为 Qt 会自动管理这种情况。所以你(可能的)问题来自于使用 boost 线程。

但是,有一个简单的解决方案:确保使用Qt::QueuedConnection. 这会将一个事件发布到 Widget 线程的事件循环中并执行该线程中的插槽。(当对象存在于不同的线程中时,这就是使用 QThreads 自动执行的操作)。

请注意,在这种情况下,插槽执行将是异步的。如果您需要同步执行槽(即所有槽必须在发出信号的代码继续之前完成),请使用Qt::BlockingQueuedConnection

于 2013-08-28T09:20:57.200 回答
0

这取决于连接。如果连接是直接的,则发射线程将用于将信号传递到已连接的插槽。这安全吗?这取决于插槽。特别是,slots onQWidget无法处理这个问题。如果连接排队,则存储信号。接收器对象有一个关联的 QThread,该线程有一个事件循环,并且该事件循环会将存储的信号传递给接收器。

您的问题描述了排队连接的行为。这是一个有效的可能性。Qt 事件循环是线程安全的。向它传递信号和从中调用槽都得到了适当的保护。由于每个接收器只有一个 QThread,这意味着排队的信号是按顺序传递的。

于 2013-08-28T12:52:08.440 回答