问题:如果不进行子类化,如何清理QThread?

时间:2015-02-23 08:01:46

标签: c++ multithreading qt

如果我有最标准的使用QThread的代码:

myClass* object = new myClass();
QThread* worker = new QThread();
object->moveToThread(worker);
worker->start();

那么删除 object 的正确方法是什么,以及退出 worker 线程的正确方法?

如果我不删除对象,则会出现内存泄漏。

如果我不退出 worker ,当我关闭应用程序时,会有警告说QThread在它仍在运行时被销毁。

3 个答案:

答案 0 :(得分:3)

要删除object对象,您可以将worker对象的QThread::finished信号连接到object对象的QObject::deleteLater位置。

要退出线程,您可以在类的析构函数中调用QThread::quitQThread::wait(或者在需要停止线程时)。

MyClass::~MyClass()
{
    thread->quit();
    thread->wait();
    ...
}

要删除worker对象,您只需设置父对象,或将其设为自动成员变量即可。您也可以使用智能指针。

顺便说一下,你的命名约定有点奇怪。您的案例中的QThread对象不是工作者,它只是管理线程。 myClass对象将是您案例中的工作者。

答案 1 :(得分:0)

这是一个基本用法:

定义一个工人类:

class MyWorkerClass {
    signals:
    void Finished();

    public slots:
    void RunCode(){
        //...
        // add your code here
        //...
        emit Finished();
    }
}

如何使用您的工人类:

MyWorkerClass * workerObject = new MyWorkerClass();
QThread * workerThread = new QThread();

workerObject->moveToThread(workerThread);

connect(workerThread, &QThread::started, workerObject, &MyWorkerClass::RunCode);
connect(workerObject, &MyWorkerClass::Finished, workerThread, &QThread::quit);

workerThread->start();
workerObject->deleteLater();

答案 2 :(得分:0)

连接QThread::finishedQObject::deleteLater是错误的。如果发出信号QThread::finished,则意味着线程事件循环不会再次运行,因此不会调用slot QObject::deleteLater。所以接受的答案是错误的。

最好这样做:

myClass* object = new myClass();
QThread* worker = new QThread(parent);
object->moveToThread(worker);

connect(object, &QObject::destroyed, worker, &QThread::quit, Qt::DirectConnection);
connect(someObject, SIGNAL(stoItSignal()), object, &QObject::deleteLater);
worker->start();

在某些时候可能需要等待踏板(例如当主窗口被销毁时)来清理东西,所以这个声明可能很有用(在这种情况下,上面代码中的Qt::DirectConnection是强制性的) :

object->deleteLater();
worker->wait(3000);