gpt4 book ai didi

c++ - 无法在 QThread 与多个 Qthread 的 finished() 信号之间进行连接

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:37:03 29 4
gpt4 key购买 nike

我有 3 个 QThreads 相互调用(全部继承自 QThread。我知道有些人可能建议使用 moveToThread,但暂时忽略这个事实)。简化的代码如下所示:

Thread1 类:

void
Thread1::run
{
// some execution
Thread2 t2 = new Thread2();
connect(t2,SIGNAL(finished),this,SLOT(onFinished));
t2->start();

while(!stop) // stop was initialized as false
{
this->msleep(10);
}
}
void Thread1::onFinished(){ stop = true; }

线程2类:

void
Thread2::run
{
// some execution
Thread3 t3 = new Thread3();
connect(t3,SIGNAL(finished),this,SLOT(onFinished));
t3->start();

while(!stop) // stop was initialized as false
{
this->msleep(10);
}
}
void Thread2::onFinished(){ stop = true; }

线程3类:

void
Thread3::run
{
// some execution
QMutexLocker ml(&mMutex);
}

当我只有两个线程时,它工作得很好(例如只有线程 2 和线程 3)。在我转到三线程场景后,onFinished() 方法似乎不再正确连接 finished() 信号。 thread2 中的 onFinished() 曾经被调用过。而且我很确定 thread3 的执行已经完成。

谁能告诉我哪里做错了?

最佳答案

首先你应该注意默认的连接类型是Qt::AutoConnection。这意味着如果信号是从与接收对象的线程不同的线程发出的,则使用 Qt::QueuedConnection。在这种情况下: 当控制权返回到接收者线程的事件循环时调用槽。插槽在接收方的线程中执行。因此您需要一个事件循环。

它适用于 2 个线程,因为您可能在主线程中运行了一个事件循环。在您仅使用 thread2thread3 对象的情况下, thread2 对象实际上将存在于主线程中,而 thread3 对象将存在于由 thread2 对象管理的线程中。所以 thread2 对象中的插槽应该可以工作。

但是在3线程的情况下,thread1对象会在主线程中,thread2对象会在thread1管理的线程中> 对象,并且因为那里没有正在运行的事件循环,所以永远不会执行 thread2 对象中的槽。

您可以调用QThread::exec()在您的 QThread::run() 函数中,但请注意,插槽将在您的 QThread 对象所在的线程中执行,而不是在它管理的线程中执行。因此,您不应在 QThread 子类中使用插槽。您应该创建一个 QObject 子类并将其移动到一个线程。

当您将信号连接到插槽时,另一种选择是使用 Qt::DirectConnection 作为连接类型。

关于c++ - 无法在 QThread 与多个 Qthread 的 finished() 信号之间进行连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19374218/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com