在Qt中,为什么调用线程对象的wait()函数会阻止它接收信号?

问题描述 投票:0回答:1
    QThread *ptr=new QThread();
    Worker *pwk=new Worker();
    ptr->setObjectName("Worker thread");
    pwk->moveToThread(ptr);
    QObject::connect(ptr,&QThread::started,pwk,&Worker::run);
    QObject::connect(pwk,&Worker::finished,ptr,[ptr](){
                    qInfo()<<"get finished signal to quit";
                    ptr->quit();});
    ptr->start();
    if(!ptr->wait(5000))
    {
        qInfo()<<ptr<<"is still running:"<<ptr->isRunning();
    }
    qInfo()<<"exit from"<<Q_FUNC_INFO;

上面的代码是在主线程中执行的。 Worker::finished 信号已发出,通过在 ptr->wait(5000) 返回之前执行连接到该信号的某些 pwk 槽函数(上面未显示)来验证该信号。但是,直到 ptr->wait(5000) 返回时,ptr 才会收到完成信号。所有连接调用都会返回成功。看来pwk自己的函数正常执行,而ptr自己的事件循环没有响应事件,而ptr->wait被阻塞。 可能的原因是什么?

qt signals-slots qthread
1个回答
0
投票
QObject::connect(pwk,&Worker::finished,ptr,[ptr](){
                    qInfo()<<"get finished signal to quit";
                    ptr->quit();},Qt::DirectConnection);

添加 Qt::DirectConnection 后,它按预期工作。 我问了chatGPT,它的回答如下:

线程关联性和连接类型

  1. Qt 的默认行为:

当省略连接类型时,Qt 使用自动连接 (Qt::自动连接)。使用 Qt::AutoConnection:如果发送者 (pwk) 和 接收者(ptr)在同一个线程中,Qt使用直接连接。如果 它们位于不同的线程中,Qt 使用排队连接。

  1. 您案例中的线程亲和力:

pwk 被移动到 ptr 的线程(ptr 是一个 QThread 对象)。然而, QThread对象(ptr)本身仍然与主线程相关联, 不是它自己的线程。这是因为 QThread 对象代表 线程但并不存在于其中。它的信号和槽在中处理 它被创建的线程(这里是主线程)。

我检查了 pwk->thread() 是 ptr 的,而 ptr->thread 是主线程的。所以我相信这是因为Qt默认使用排队连接来连接发送者(pwk)和接收者(主线程),它将信号发送到主线程的事件循环。而主线程通过调用ptr->wait()而被阻塞,只有从wait返回后才能响应,然后调用槽函数ptr->quit()。

© www.soinside.com 2019 - 2024. All rights reserved.