版权声明:课程笔记内容整理于狄泰软件 https://blog.csdn.net/qq_39654127/article/details/82018872
1、另一种创建线程的方式
历史的痕迹
class QThread : public QObject
{
//...
protected:
virtual void run()= 0;
/*
* 面向对象程序设计实践的早期,工程中
* 习惯于通过继承的方式扩展系统的功能。
*/
}
现代软件架构技术
参考准则:
尽量使用组合的方式实现系统功能
代码中仅体现需求中的继承关系
除了重写的run不同,其它接口完全相同
结论
-通过继承的方式实现多线程没有任何实际意义
-QThread对应于操作系统中的线程
-QThread用于充当一个线程操作的集合
-应该提供灵活的方式指定线程入口函数
-尽量避免重写void run()
QThread类的改进
class QThread : public QObject
{
//...
protected:
virtual void run() //新版本QT
{
(void)exec(); //默认开启事件循环
}
//...
}
如何灵活的指定一个线程对象的线程入口函数?
解决方案-信号与槽
1. 在类中定义一个槽函数void tmain()作为线程入口函数
2. 在类中定义一个QThread成员对象m_thread
3. 改变当前对象的线程依附性到m_thread
4 连接m_thread的start()信号到tmain()
2、编程实验
另一种创建线程的方式 83-1.pro
AnotherThread.h
#ifndef ANOTHERTHREAD_H
#define ANOTHERTHREAD_H
#include <QObject>
#include <QThread>
class AnotherThread : public QObject
{
Q_OBJECT
QThread m_thread;
protected slots:
void tmain();//线程入口函数
public:
explicit AnotherThread(QObject *parent = 0);
void start();
void terminate();
void exit(int c);
~AnotherThread();
};
#endif // ANOTHERTHREAD_H
AnotherThread.cpp
#include "AnotherThread.h"
#include <QDebug>
AnotherThread::AnotherThread(QObject *parent) :
QObject(parent)
{
moveToThread(&m_thread);
connect(&m_thread, SIGNAL(started()), this, SLOT(tmain()));
}
void AnotherThread::tmain()
{
qDebug() << "void AnotherThread::tmain() tid = " << QThread::currentThreadId();
for(int i=0; i<10; i++)
{
qDebug() << "void AnotherThread::tmain() i = " << i;
}
qDebug() << "void AnotherThread::tmain() end";
m_thread.quit();
}
void AnotherThread::start()
{
m_thread.start();//m_thread线程开启,定义的tmain函数被调用(run函数也被调用,开启事件循环)
}
void AnotherThread::terminate()
{
m_thread.terminate();
}
void AnotherThread::exit(int c)
{
m_thread.exit(c);
}
AnotherThread::~AnotherThread()
{
m_thread.wait();//同步设计,保证线程生命周期大于对象声明周期
}
main.cpp
#include <QtCore/QCoreApplication>
#include <QDebug>
#include <QThread>
#include "AnotherThread.h"
void test()
{
AnotherThread at;
at.start();
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << "main() tid = " << QThread::currentThreadId();
test();
return a.exec();
}
灵活的指定tmain为线程入口函数
3、小结
早期的Qt版本只能通过继承的方式创建线桯
现代软件技术提倡以组合的方式代替继承
QThread应该作为线程的操作集合而使用
可以通过信号与槽的机制灵活指定线程入口函数