繁体   English   中英

信号/插槽多线程Qt

[英]Signal/slot multithreading Qt

我知道这是关于线程之间的连接信号/插槽机制的下一个问题。 我写了工作中的工作程序。

主要问题

我的工作人员班级已移至另一个线程。 应用程序的第二部分是带有按钮的GUI界面。 当我单击按钮时,线程开始:

void MainWindow::startStopThreadA()
{
    ...
    else
    {
        threadA = new QThread;
        workerA = new WorkerObject;
        workerA->setMessage("Thread A running");
        workerA->moveToThread(threadA);

        connect(threadA, SIGNAL(started()), workerA, SLOT(process()), Qt::QueuedConnection);
        connect(workerA, SIGNAL(finished()), threadA, SLOT(quit()));
        connect(workerA, SIGNAL(finished()), workerA, SLOT(deleteLater()));
        connect(threadA, SIGNAL(finished()), threadA, SLOT(deleteLater()));
        //Connect signal from thread with slot from MainWindow
        connect(workerA, SIGNAL(printMessage(QString)), this, SLOT(printMessage(QString)), Qt::QueuedConnection);

        threadA->start();
        ui->threadAButton->setText("Stop A");
    }
}

当线程启动时发出信号:

void WorkerObject::process(void)
{
    //Infinity thread loop
    forever
    {
        //Exit loop part
        mutex.lock();
        if(m_stop)
        {
            m_stop = false;
            mutex.unlock();
            break;
        }
        mutex.unlock();

        //Hold/unhold loop part
        mutex.lock();
        if(!m_hold)
        {
            mutex.unlock();
            //Here signal is emited
            emit printMessage(messageStr);          //That not works
            //qDebug() << "Thread A test message."; //That works properly
        }
        mutex.unlock();
    }
    emit finished();
}

在主GUI线程中,我有计时器来显示GUI线程的工作原理。 所以qDebug()可以正常工作并从我的线程中打印消息。 GUI线程中的计时器也可以正常工作,并在textEdit GUI字段内打印消息。

现在,当printMessage信号时,GUI线程执行slot方法:

void MainWindow::printMessage(QString str)
{
    ui->textEdit->append(str);
}

这是我的问题中最重要的部分:

当来自workerA对象的信号printMessage与带有Qt::QueuedConnection GUI插槽printMessage连接时, 我的应用程序挂断了 无法单击某些按钮,甚至无法退出应用程序。

当信号/插槽与Qt::BlockingQueuedConnection连接时,一切正常。 在线程之间发出和接收消息,并且GUI计时器也可以正常工作。

所以我的问题是为什么连接Qt::QueuedConnection导致应用程序冻结?

我通过@ m7913d帮助找出了这个问题。

您可以尝试在您的永远循环(fe 1秒)内执行QThread :: sleep,以检查它是否解决了您的问题。

因此,工作线程过于频繁地发出信号。 在发出信号后添加QThread::msleep(5)确实有帮助。 也需要包含在内。

暂无
暂无

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

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