在析构函数中调用退出不会杀死 QThread?

Calling quit in destructor doesn't kill the QThread?

本文关键字:QThread 析构函数 调用 退出      更新时间:2023-10-16

我通过QtCreator运行这段代码。
问题是当我关闭输出窗口时,线程不会死亡。要杀死线程,我必须转到终端并通过找到其 ID 手动杀死它Application output或使用窗口上的红色方块按钮杀死它。

除非我们按 Alt F4 关闭窗口,否则此应用程序应该永远运行。

源文件 [cpp]:

#include "mainwindow.h"
Controller::Controller(QMainWindow *parent) : QMainWindow(parent)
{
    worker_obj.moveToThread(&workerThread);
    worker_obj.timerReceivePackets.moveToThread(&workerThread);
    connect(this, &Controller::operate, &worker_obj, &Worker::doSomething);
    connect(&workerThread, SIGNAL(started()), &worker_obj, SLOT(initialize()));
    connect(&worker_obj, &Worker::resultReady, this, &Controller::handleResults);
    connect(&workerThread, SIGNAL(finished()), &workerThread, SLOT(deleteLater()));
    workerThread.start();
}
Controller::~Controller()
{
    workerThread.wait();
    workerThread.quit();
    workerThread.terminate();
}

页眉 [h]

#ifndef Worker_H
#define Worker_H
#include <QMainWindow>
#include <QObject>
#include <QImage>
#include <QDebug>
#include <QThread>
#include <QTimer>
class Worker : public QObject
{
    Q_OBJECT
private:
public:
    QTimer timerReceivePackets;
    Worker(QObject * parent = 0) {}
    ~Worker() {}
public slots:
    void initialize()
    {
        connect (&timerReceivePackets, SIGNAL (timeout()),
                 this, SLOT (doSomething()));
        timerReceivePackets.start();
    }
    void doSomething()
    {
        while(1)
        {
            QString result;
                /* ... here is the expensive or blocking operation ... */
            emit resultReady(result);
        }
    }
signals:
    void resultReady(const QString &result);
};
class Controller : public QMainWindow
{
    Q_OBJECT
    QThread workerThread;
public:
    Worker worker_obj;
    Controller( QMainWindow *parent = 0 );
    ~Controller();
public slots:
    void handleResults(const QString &) {}
signals:
    void operate(const QString &);
};
#endif // Worker_H
下面是

使用QWidget::closeEvent要求worker完成其任务的解决方案。忽略立即窗口关闭(当主窗口有问题时应用程序退出(以正常终止线程,并且仅在工作线程完成后退出应用程序。这样就可以在退出应用程序之前保存线程中执行的昂贵操作的状态。工作线程完成后QObject::deleteLater将调用 worker 和线程QThread::quit线程,该线程在完全关闭后触发 deleteLater。

控制器:

class Controller : public QMainWindow
{
    Q_OBJECT
public:
    explicit Controller(QMainWindow *parent = nullptr)
        : QMainWindow(parent), m_worker(new Worker)
    {
        QThread *thread = new QThread;
        m_worker->moveToThread(thread);
        connect(thread, &QThread::started, m_worker, &Worker::operate);
        connect(m_worker, &Worker::resultReady, this, &Controller::handleResults);
        connect(m_worker, &Worker::finished, thread, &QThread::quit);
        connect(thread, &QThread::finished, thread, &QObject::deleteLater);
        connect(m_worker, &Worker::finished, m_worker, &QObject::deleteLater);
        connect(m_worker, &Worker::finished, qApp, &QApplication::quit);
        thread->start();
    }
    virtual ~Controller() {}
public slots:
    void handleResults(const QString &result){
        qDebug() << result;
    }
protected:
    void closeEvent(QCloseEvent *event) override
    {
        m_worker->finish();
        event->ignore();
    }
private:
    Worker *m_worker;
};

工人:

class Worker : public QObject
{
    Q_OBJECT
public:
    explicit Worker(QObject *parent = nullptr)
        : QObject(parent), m_continue(false) {}
    virtual ~Worker() {}
public slots:
    void operate(){
        m_continue = true;
        static QString result;
        while(m_continue)
        {
            result.append('a');
            QThread::sleep(2);
            emit resultReady(result);
        }
        emit finished();
    }
    void finish() {
        m_continue = false;
    }
signals:
    void finished();
    void resultReady(const QString &result);
private:
    bool m_continue;
};