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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宇龍_

若帮助到你,希望能给予鼓励!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值