繁体   English   中英

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

[英]Unable to connect between QThread with finished() signal for multiple Qthread

我有一个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; }

Thread2类:

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; }

Thread3类:

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

当我只有两个线程时,它完全正常(例如,只有thread2和thread3)。 在我转移到三线程场景之后,onFinished()方法似乎不再正确连接finished()信号。 已经调用了thread2中的onFinished()。 而且我很确定thread3的执行已经完成。

谁能告诉我哪里可能做错了?

首先,您应该注意默认连接类型是Qt::AutoConnection 这意味着如果从与接收对象的线程不同的线程发出信号,则使用Qt::QueuedConnection 在这种情况下: The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread. The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread. 所以你需要一个事件循环。

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM