简体   繁体   English

Qt从GUI线程停止工作线程循环

[英]Qt Stop worker thread loop from GUI Thread

i have a worker thread which i try to stop through a button. 我有一个工作线程,我试图通过一个按钮停止。 i sometimes get the following error: 我有时会收到以下错误:

Fatal: QThread: Destroyed while thread is still running

Here is my code. 这是我的代码。 By pushing the disconnect button a signal is emitted to stop the thread's while loop. 通过按下断开连接按钮,将发出信号以停止线程的while循环。

if (ui->connectButton->text() == "Connect") {
    mUDPThread = new QThread;
    mUDPWorker = new  UDPThread(ui->HostTextEdit->toPlainText(), ui->portTextEdit->toPlainText().toInt());
    mUDPWorker->moveToThread(mUDPThread);
    connect(mUDPThread, SIGNAL(started()), mUDPWorker, SLOT(process()));
    connect(mUDPWorker, SIGNAL(finished()), mUDPThread, SLOT(quit()));
    connect(mUDPWorker, SIGNAL(finished()), mUDPWorker, SLOT(deleteLater()));
    connect(mUDPWorker, SIGNAL(finished()), mUDPThread, SLOT(deleteLater()));
    connect(this, SIGNAL(onExitThread()), mUDPWorker, SLOT(onExitThread()));
    connect(this, SIGNAL(onDataIncome(QString)), mUDPWorker, SLOT(onDataIncome(QString)));
    mUDPThread->start();
    ui->connectButton->setText("Disconnect");
} else if (ui->connectButton->text() == "Disconnect") {
    emit onExitThread();
    ui->connectButton->setText("Connect");
}

the worker Thread: 工作线程:

void UDPThread::process() {
    while (isRunning) {
    QCoreApplication::processEvents();
      ...
    }
    emit finished();
}
void UDPThread::onExitThread() {
    qDebug() << "onExitThread" << isRunning;
    isRunning = false;
}

while (isRunning)

You are blocking the thread right there, its event loop cannot spin in order to receive signals, it can only send signals to other threads with spinning event loops. 您正在此处阻塞线程,其事件循环无法旋转以接收信号,它只能将信号发送给具有旋转事件循环的其他线程。

You need to make your worker non-blocking, split the work in cycles, in between the event loop gets to spin and receive signals. 您需要使工作人员无阻塞,将工作分成多个周期,在事件循环之间旋转并接收信号。 In pseudocode: 用伪代码:

if (isRunning) {
  doWorkCycle();
  scheduleNextWorkCycle();
} else emit finished();

There is an example you can look at here . 您可以在此处查看一个示例。

Solved it. 解决了。 The error was within the connect commands: 错误在连接命令内:

connect(mUDPWorker, SIGNAL(finished()), mUDPThread, SLOT(deleteLater()));

to

connect(mUDPThread, SIGNAL(finished()), mUDPThread, SLOT(deleteLater()));

result: 结果:

connect(mUDPThread, SIGNAL(started()), mUDPWorker, SLOT(process()));
connect(mUDPWorker, SIGNAL(finished()), mUDPThread, SLOT(quit()));
connect(mUDPWorker, SIGNAL(finished()), mUDPWorker, SLOT(deleteLater()));
connect(mUDPThread, SIGNAL(finished()), mUDPThread, SLOT(deleteLater()));
connect(this, SIGNAL(onExitThread()), mUDPWorker, SLOT(onExitThread()));
connect(this, SIGNAL(onDataIncome(QString)), mUDPWorker, SLOT(onDataIncome(QString)));

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

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