gpt4 book ai didi

c++ - 等待 qthread 终止的正确方法是什么?

转载 作者:行者123 更新时间:2023-11-30 02:18:08 27 4
gpt4 key购买 nike

我想知道创建 QThread 对象、终止它并等待主线程终止的正确方法。

我遇到的问题是 QThread 的 wait() 方法没有返回 true(正如我认为的那样)并且一直阻塞直到超时到期。

我通过在工作线程中从 run() 方法返回之前调用 quit() 方法暂时解决了这个问题,但我认为这不应该是正确的方法。

QT Documentation说如果线程已经完成 wait() 应该返回 true

(i.e. when it returns from run())

我正在使用 QT 5.9 和 Linux。

有人遇到过这个问题吗?

主窗口.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

# include <QMainWindow>
# include "Worker.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow {
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();

private slots:
void on_btnStart_clicked();
void on_btnStop_clicked();

private:
Worker *ProcWorker;
QThread ProcessThread;
Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

主窗口.cpp:

# include "MainWindow.h"
# include "ui_MainWindow.h"

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
ui->setupUi(this);

this->ProcWorker = new Worker ();
this->ProcWorker->moveToThread(&this->ProcessThread);
QObject::connect (&this->ProcessThread, SIGNAL(started()), this->ProcWorker, SLOT(RunProcess()));
}

MainWindow::~MainWindow() {
delete ui;
}

void MainWindow::on_btnStart_clicked() {
this->ProcessThread.start ();
}

void MainWindow::on_btnStop_clicked() {
this->ProcWorker->Terminate ();

// It blocks until timeout has expired and return false.
bool ret = this->ProcWorker->thread()->wait (1000000);
}

Worker.h:

#ifndef WORKER_H
#define WORKER_H

# include <QObject>
# include <QThread>

class Worker : public QObject {
Q_OBJECT
private:
bool TerminateProcess;

public:
Worker() {
this->TerminateProcess = false;
}

void Terminate () {
this->TerminateProcess = true;
}

public slots:
void RunProcess () {
while (true) {
QThread::msleep(100);
if (this->TerminateProcess) {
break;
}

// Do something
}

// I need to add this to get wait() works
//this->thread()->quit ();
}
};

#endif

最佳答案

线程不会因为 RunProcess 结束而停止运行。发送 quit 是关闭线程的正确方法。

也就是说,您还有另外两个与线程相关的问题:

  • 不能保证在 RunProcess 中看到您的 TerminateProcess 标志。您应该使用 QAtomicIntQSemaphore 来确保工作线程看到标志更改。
  • 如果您从外部(或在Terminate)调用quit,您的RunProcess 方法会阻止事件循环运行并关闭线程>).您应该在 QTimer 的回调中“做某事”或使用线程中断机制(调用者的 QThread::requestInterruptionQThread::interruptionRequested 在循环内)。

很大程度上取决于您的“做某事”代码。如果在不支持中断方式的情况下花费几分钟计算 Pi 的数字,那么与它外部的 Qt 事件循环进行再多的合作也救不了你。

关于c++ - 等待 qthread 终止的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52596409/

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