我以一种我以前常常看到的非常不同的方式使用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:我使用宏来创建信号和插槽,因此我不会那么打字。
答案 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。