Qt - 评估我的QThread方法。删除部分崩溃

时间:2018-01-18 22:47:52

标签: qt qthread

我以一种我以前常常看到的非常不同的方式使用QThread。 看看:

#include <QObject>
#include <QThread>

class CustomWorker : public QObject
{
    Q_OBJECT

public:
    CustomWorker()
    {
        _thread = new QThread();
        this->moveToThread(_thread);
        _thread->start();

        connect(_thread, SIGNAL(finished()), this, SLOT(threadFinished()));

        connect(this, SIGNAL(process1Signal()), this, SLOT(process1Slot()));
        connect(this, SIGNAL(process2Signal()), this, SLOT(process2Slot()));
    }

    void deleteMe()
    {
        _thread->quit();
    }

public:
    void process1(){ emit process1Signal(); }
    void process2(){ emit process2Signal(); }

signals:
    void process1Signal();
    void process2Signal();

private slots:
    void process1Slot(){ /* code to run in background */ }
    void process2Slot(){ /* code to run in background */ }

    void threadFinished()
    {
        _thread->deleteLater();
        this->deleteLater();
    }

private:
    QThread* _thread;
};

因此,我可以使用CustomWorker直接调用函数process1()或process2():

_worker = new CustomWorker;
connect(_worker, SIGNAL(process1Ended()), this, SLOT(handleProcess1()));
connect(_worker, SIGNAL(process2Ended()), this, SLOT(handleProcess2()));
...
_worker->process1();

它工作正常......但删除部分有时会崩溃:

_worker->deleteMe();

我不知道发生了什么。实现它的正确方法是什么?

PS:我使用宏来创建信号和插槽,因此我不会那么打字。

2 个答案:

答案 0 :(得分:0)

我认为问题在于您可能在完成之前删除了一个帖子。因此,请按以下方式更改void deleteMe() { _thread->quit(); _thread->wait(); // just add this line } 方法:

{{1}}

不建议删除班级内的对象。

答案 1 :(得分:0)

你的问题是线程亲和力;一个对象正在运行的线程。请注意,CustomWorker实际上不是一个线程,但更像是一个线程控制器。

QThread

假设在主(gui)线程上实例化moveToThread(_thread)对象。它的构造函数创建_worker成员实例,它也在主线程上。

在调用_thread之后,CustomWorker对象现在已移至新线程。线程实例QThread不是QThread类的子节点,因此它保留在主线程上。当调用delete时,您现在正在尝试删除mlen对象,该对象位于与您要删除的对象不同的线程上。

要解决此问题,请将QThread移出CustomerWorker类。线程应该对其上运行的对象唯一的关联是通过moveToThread函数。

请考虑您的设计应该允许一个QThread对象和多个可以在该一个线程上运行的工作者实例。

有关mlen的详情,建议您阅读this blog post