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

问题描述 投票:0回答:3

我以一种与我习惯看到的非常不同的方式使用 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:我使用宏来创建信号和槽,所以我不会输入太多这样的内容。

qt qthread
3个回答
0
投票

我认为问题在于您可能会在线程完成之前删除它。因此,请更改您的

deleteMe()
方法,如下所示:

void deleteMe()
{
    _thread->quit();
    _thread->wait();  // just add this line
}

并且不建议删除类内的对象。


0
投票

你的问题是线程亲和性;对象正在哪个线程运行。请注意,

QThread
实际上并不是一个线程,而更像是一个线程控制器。

class CustomWorker : public QObject
{
public:
    CustomWorker()
    {
        _thread = new QThread();
        this->moveToThread(_thread);
    }

private:
   QThread* _thread
};

_worker = new CustomWorker;

假设一个

CustomWorker
对象在主(gui)线程上实例化。它的构造函数创建
QThread
成员实例,该实例也在主线程上。

在调用

moveToThread(_thread)
之后,
_worker
对象现已移至新线程。线程实例
_thread
不是
CustomWorker
类的子级,因此它保留在主线程上。当调用删除时,您现在尝试删除
QThread
对象,该对象与您要删除的对象驻留在不同的线程上。

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

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

有关

QThread
的更多信息,我建议阅读这篇博文


0
投票

在很多情况下,Qt 的

QThread
类需要
deleteLater()
而不是
delete
来拥有 QObject,否则会崩溃。

即使您

delete
QThread
本身也是如此:因此它应该是
myThreadPtr->deleteLater()

基本上,即使

QThread
尚未运行,也应将其视为正在运行。

© www.soinside.com 2019 - 2024. All rights reserved.