一、在子线程中实例化对象
我们创建一个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()函数中创建的对象会造成内存泄漏的问题。