Qt子线程中的对象注意点

一、在子线程中实例化对象

我们创建一个TimeThread类,继承于QObject

#ifndef TIMETHREAD_H
#define TIMETHREAD_H

#include <QObject>
#include <QTimer>
#include <QThread>
class TimeThread : public QObject
{
    Q_OBJECT
public:
    explicit TimeThread(QObject *parent = nullptr);
public slots:
    void init();
private:
    QTimer *timer;
private slots:
    void timeover();
};

#endif // TIMETHREAD_H
#include "timethread.h"
#include <QDebug>
TimeThread::TimeThread(QObject *parent) : QObject(parent)
{

}

void TimeThread::stopTimer()
{
    timer->stop();
}

void TimeThread::init()
{
    timer = new QTimer(this);
    timer->setSingleShot(false);
    connect(timer,&QTimer::timeout,this,&TimeThread::timeover);
    timer->start(1000);
}

void TimeThread::timeover()
{
    qDebug()<<"timer:"<<QThread::currentThreadId();
}

主线程

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    qDebug()<<"main:"<<QThread::currentThreadId();
    m_time = new TimeThread;
    m_thread = new QThread(this);
    m_time->moveToThread(m_thread);
    connect(m_thread,&QThread::started,m_time,&TimeThread::init);
    m_thread->start();
}

运行结果:
main: 0x39d8
timer: 0x499c
timer: 0x499c
timer: 0x499c
主线程和定时器处于两个不同线程,代码正确。

如果把定时器的实例化放在构造函数中会怎么样呢?

#include "timethread.h"
#include <QDebug>
TimeThread::TimeThread(QObject *parent) : QObject(parent)
{
    timer = new QTimer(this);
    timer->setSingleShot(false);
    connect(timer,&QTimer::timeout,this,&TimeThread::timeover);
}

void TimeThread::init()
{
    timer->start(1000);
}

结果竟然也是正常的,并没有出现QBasicTimer::start: Timers cannot be started from another thread,有点出乎我的意料。
接着尝试,从外部停止定时器会怎么样?
子线程中增加public函数

void TimeThread::stopTimer()
{
    timer->stop();
}

从主线程直接调用,出现QObject::killTimer: Timers cannot be stopped from another thread
不管timer在哪里实例化都是这样,也就是说,外部无法直接操作子线程对象。
那么试试用信号槽可不可以。
connect(this,&Widget::sig_stopTimer,m_time,&TimeThread::stopTimer);
绑定主线程的信号与子线程的停止槽函数
结论:可以,定时器停止,没有报异常

二、测试子线程和内存的关系

我在子线程中增加了一个变量,定时器每次执行后自增,执行5次后停止定时器。接着重新start线程,发现毫无反应,TimeThread::init()函数并未被执行。只有执行过QThread::quit()之后才能再次使用QThread::start()
由此得出一个结论:子线程的run()函数无法重复执行,在线程未结束之前,无法再次执行run()函数。
我在init()函数中创建数组:array = new int [204800]且没有delete,在反复多次执行后并未发现内存一直增长的问题。每次new的时候会增长一点内存使用,但是执行完QThread::quit()之后又会恢复。因此不必担心在run()函数中创建的对象会造成内存泄漏的问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值