通过QThread使用多线程技术

前言

QT实现多线程有多种方式,其中一种方式就是通过继承QThread类。本篇文章重点描述这种实现方式,后续对它的理解有新的领悟也会更新在这里。

0x0 通过QThread类创建子线程的步骤流程有几步呢?

首先,创建一个继承于QThread基类的派生类

#pragma once
#include 
class AudioDataDeal : public QThread
{
	Q_OBJECT
public:
	AudioDataDeal(void*);
};

然后,重载QThread类的虚函数run,这里编写的是子线程要执行的任务,以及子线程任务完成后通知主线程的代码

#pragma once
#include 
class AudioDataDeal : public QThread
{
	Q_OBJECT
public:
	AudioDataDeal(void*);
protected:
	void run() override;
signals:
	void finish(const QString&);
};

接着,创建派生类对象,调用槽函数start

void QTheadTest::ExeTask() {
	if (m_task == nullptr) {
		m_task = new AudioDataDeal(this);
		m_task->start();
	}
	else m_task->start();
}

0x1 主-子线程通信方式有几种?

可以通过槽函数触发主线程进行对应的处理

AudioDataDeal::AudioDataDeal(void* thiz) {
	connect(this, &AudioDataDeal::finish, (QTheadTest*)thiz, &QTheadTest::NoticeView);
}
void AudioDataDeal::run()
{
	for (int i = 0; i < 10000; i++) qDebug() << i;
	qDebug() << "task exe finished";
	emit finish("Child Thread exe task finished");
}

在重载的虚函数run中直接更新界面,或者直接调用主线程中的函数,网上说主线程和子线程之间如果要进行数据的传递,必须使用Qt中的信号槽机制! ,但是这种方式不就验证了这句话是错的?也有可能是自己理解还不够,后面再研究

void AudioDataDeal::run()
{
	for (int i = 0; i < 10000; i++) qDebug() << i;
	qDebug() << "task exe finished";
	emit finish("Child Thread exe task finished");
	g_ptr->ui.thread_exe_info->setText("Child Thread exe task finished");
	//or g_ptr->NoticeView("Child Thread exe task finished");
}

0x2 在什么环境下需要用到多线程呢?

①某些操作比较耗时,会造成主线程的阻塞,从而导致主界面卡顿【验证方式:把耗时的操作放在主线程,然后移动主界面】,影响用户的使用体验
②主机硬件配置低,耗时的操作会直接导致主线程卡死,处理不过来

0x4 怎么保证子线程安全的退出呢?

窗口关闭等可能导致主线程结束的事件进行以下处理,从而保证子线程安全退出前主线程不会突然结束掉

m_threadTask->quit();
m_threadTask->wait();
m_threadTask = nullptr;

0x3 总结

待总结

你可能感兴趣的:(#,QT,多线程,QThread)