在Qt中,使用线程主要有两种方式。
1、自定义线程类,继承自QThread,并重写run方法即可。该方法就不再阐述了。
2、就是推荐使用的方法。
示例代码如下:
1、自定义Worker类,将线程中的逻辑在该类中以槽函数的方式实现:
Worker.h
#ifndef WORKER_H
#define WORKER_H#include <QObject>class Worker : public QObject
{Q_OBJECT
public:explicit Worker(QObject *parent = nullptr);~Worker();public slots:void doSomething();
};#endif // WORKER_H
Worker.cpp
#include "worker.h"
#include <QDebug>Worker::Worker(QObject *parent) : QObject(parent)
{}Worker::~Worker()
{qDebug()<<"free worker...";
}void Worker::doSomething()
{qDebug()<<"do something...";
}
2、调用处的代码
QThread *thread = new QThread;Worker* worker = new Worker;connect(thread,SIGNAL(started()),worker,SLOT(doSomething()));connect(thread,SIGNAL(finished()),worker,SLOT(deleteLater()));connect(thread,SIGNAL(finished()),thread,SLOT(deleteLater()));worker->moveToThread(thread);thread->start();
以上代码非常清晰易懂,在线程开始的时候触发Worker的doSomething槽函数,当线程结束的时候调用Worker的deleteLater槽函数以释放new出来的worker对象和thread对象。
但是问题出现了!thread线程永远不会结束!其原因是虽然worker对象的doSomething槽函数结束了,但是thread线程依然处于自己的事件循环中!也就导致了thread和worker的内存泄漏!
正确的处理办法:在worker对象的槽函数doSomething结束的时候,应发射结束信号来间接控制线程!具体代码如下:
Worker.h
#ifndef WORKER_H
#define WORKER_H#include <QObject>class Worker : public QObject
{Q_OBJECT
public:explicit Worker(QObject *parent = nullptr);~Worker();
signals:void finished();//完成信号public slots:void doSomething();
};#endif // WORKER_H
Worker.cpp
#include "worker.h"
#include <QDebug>Worker::Worker(QObject *parent) : QObject(parent)
{}Worker::~Worker()
{qDebug()<<"free worker...";
}void Worker::doSomething()
{qDebug()<<"do something...";emit finished();
}
调用处代码:
QThread *thread = new QThread;Worker*worker = new Worker;connect(worker,SIGNAL(finished()),thread,SLOT(quit()));//新增connect(thread,SIGNAL(started()),worker,SLOT(doSomething()));connect(thread,SIGNAL(finished()),worker,SLOT(deleteLater()));connect(thread,SIGNAL(finished()),thread,SLOT(deleteLater()));worker->moveToThread(thread);thread->start();
这样就可以保证,在worker对象结束任务时,thread也退出了事件循环并发射finished信号且释放内存!