Qt子线程中的对象注意点

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

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

#ifndef TIMETHREAD_H
#define TIMETHREAD_H

#include 
#include 
#include 
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 
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 
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()函数中创建的对象会造成内存泄漏的问题。

你可能感兴趣的:(qt,开发语言)