同时从多个线程调用widget的信号函数是否安全?当多个线程同时调用某个小部件的信号时,Qt是否会使用某种内部互斥锁来提供自己的数据结构的安全性?
据我了解,这是安全的,N个信号功能的同时调用将导致连续信号的N次连续调用。
我是对的吗?
P.S。 调用信号函数的线程是使用boost创建的。我认为,这对于这个问题并不重要。我不能使用另一个线程,因为那些线程只与GUI无关,但是它们服务于程序的许多部分。
答案 0 :(得分:1)
简而言之,你不会发出信号,你会发出信号。然后Qt在内部处理信号连接的任何插槽的触发。
根据连接类型,发出信号并使其发射插槽可能是也可能不是线程安全的。
阅读here了解详情。
我认为由boost创建的线程将是一个问题 - 信号/插槽机制依赖于QThread和QObject的基础结构。如果你可以使用QThread而不是一个提升线程,它可能会更好更简单。
答案 1 :(得分:0)
如果你要使用QThreads,那就没有任何问题,因为Qt会自动管理这种情况。因此,使用boost线程会产生(可能)问题。
但是,有一个简单的解决方案:确保使用Qt::QueuedConnection
连接信号和插槽。这会将事件发布到Widget的线程的事件循环中并执行该线程中的插槽。 (当对象居住在不同的线程中时,这就是使用QThreads自动执行的操作)。
请注意,在这种情况下,插槽执行将是异步的。如果需要同步执行插槽(即必须在发出信号的代码继续之前完成所有插槽),请使用Qt::BlockingQueuedConnection
答案 2 :(得分:0)
这取决于连接。如果连接是直接的,则发射线将用于将信号传递到连接的插槽。这样安全吗?这取决于插槽。特别是QWidget
上的插槽无法处理此问题。如果连接排队,则存储信号。接收器对象具有关联的QThread,该线程具有事件循环,并且该事件循环将存储的信号传递给接收器。
您的问题描述了排队连接的行为。这是一个有效的可能性。 Qt事件循环是线程安全的。向它发送信号和从中调用插槽都得到了适当的保护。由于每个接收器只有一个QThread,这意味着按顺序传送排队的信号。