使用moveToThread时的内存释放以及注意事项

版权声明:本文为博主原创文章,欢迎转载,请标明出处。 https://blog.csdn.net/Think88666/article/details/86531118

在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信号且释放内存!

猜你喜欢

转载自blog.csdn.net/Think88666/article/details/86531118
今日推荐