一、基础知识
1、多线性的优点:
- 提高应用程序的相应速度。通常情况下,应用程序都在一个线程中执行,当调用一个耗时操作时,用户界面会冻结。多线程可以解决这个问题。
- 使得多CPU系统更加有效。当线程不超过CPU数目时,操作系统可以调度不同的系统运行在不同的CPU上。
- 改善程序结构,一个既长又复杂的进程可以分成多个线程。
2、多线程的特点:
- 多线程的行为无法预测,当多次执行上述应用程序时,每一次运行的结果可能不同。
- 多线程的执行顺序无法保证,它与操作系统的调度策略和线程优先级等因素有关。
- 多线程的切换可以发生在任何时刻、任何地点。
- 多线程对代码的敏感度高。
3、Qt有两种多线程的方法,其中一种是继承QThread的run函数,另外一种是把一个继承于QObject的类转移到一个Thread里。
二、继承QThread
(1)特点
- QThread只有run函数是在新线程里,其他所有函数都在QThread生成的函数。
- 当run()函数运行完毕后,该线程的生命周期结束
(2)使用步骤
- 新建一个类workThread,基类为QThread
- 重写workThread类的虚函数,即新建个函数protected void run(),然后对其进行定义
- 在需要开启线程的地方,实例workThread类,然后调用函数workThread->start()后,开启一条线程,自动运行函数run()
- 当停止线程时,调用workThread->wait(),等待线程结束,并且回收线程资源
1、workThread.h文件编写
#ifndef WORKTHREAD_H
#define WORKTHREAD_H
#include <QThread>
class WorkThread : public QThread
{
Q_OBJECT
public:
WorkThread();
protected:
void run();
};
#endif // WORKTHREAD_H
2、workThread.cpp文件编写run()函数内容
#include "workthread.h"
#include <QtDebug>
WorkThread::WorkThread()
{
}
void WorkThread::run()
{
while(true)
{
for(int n=0;n<10;n++)
qDebug()<<n<<n<<n<<n<<n<<n<<n<<n;
}
}
3、界面中,实例化workThread,开启线程
void ThreadDlg::slotStart()
{
workThread=new WorkThread();//实例化线程类
workThread->start();//开启线程
}
4、终止线程
void ThreadDlg::slotStop()
{
workThread->terminate();
workThread->wait();
}
三、继承于QObject的类
1、使用步骤
- 首先创建一个workThread类,基类为QObject
- workThread类创建一个槽函数,槽函数中运行另一个线程运行的函数
- 实例一个QThread线程对象(容器),将类MyThread的实例对象转到该容器中,用函数void QObject::moveToThread(QThread *thread)
- 用一个信号触发该多线程槽函数
- 用信号QThread::finished绑定槽函数QThread::deleteLatater(),在线程退出时,销毁该线程和相关资源
- 所有线程初始化完成后,启动函数QThread::start()开启多线程,然后自动触发多线程启动信号QThread::started()
2、首先创建一个workThread类,基类为QObject
(1)编写workThread.h文件
#ifndef WORKTHREAD_H
#define WORKTHREAD_H
#include <QThread>
class WorkThread : public QObject
{
Q_OBJECT
public:
WorkThread();
public slots:
void startThreadSlot();//函数运行槽函数,该函数运行另一线程的代码
void closeThread();//关闭线程
//void finishedThreadSlot();
private:
volatile bool isStop;//线程运行标志位
};
#endif // WORKTHREAD_H
(2)编写workThread.cpp文件,workThread类创建一个槽函数,槽函数中运行另一个线程运行的函数
#include "workthread.h"
#include <QtDebug>
WorkThread::WorkThread()
{
isStop = false;
}
//关闭线程
void WorkThread::closeThread()
{
isStop = true;
}
//线程槽函数
void WorkThread::startThreadSlot()
{
while(true)
{
if(isStop)
return;
for(int n=0;n<10;n++)
qDebug()<<n<<n<<n<<n<<n<<n<<n<<n;
QThread::sleep(1);
}
}
2、实例一个QThread线程对象(容器),将类MyThread的实例对象转到该容器中,用函数void QObject::moveToThread(QThread *thread)
注意:deleteLater()、startThreadSlot()都不需要声明和定义
//开启线程
void ThreadDlg::slotStart()
{
firstThread = new QThread;//实例化线程容器
workThread=new WorkThread();//线程实例化
workThread->moveToThread(firstThread);//将创建的对象移到线程容器中
connect(firstThread,SIGNAL(finished()),firstThread,SLOT(deleteLater()));//终止线程时要调用deleteLater槽函数
connect(firstThread,SIGNAL(started()),workThread,SLOT(startThreadSlot())); //开启线程槽函数
connect(firstThread,SIGNAL(finished()),this,SLOT(finishedThreadSlot()));//线程完成槽函数
firstThread->start(); //开启多线程槽函数
}
3、关闭线程
//关闭线程
void ThreadDlg::slotStop()
{
if(firstThread->isRunning())
{
workThread->closeThread();//关闭线程槽函数
firstThread->quit();//退出事件循环
firstThread->wait();//释放槽函数资源
}
}
//线程销毁完成
void ThreadDlg::finishedThreadSlot()
{
qDebug()<<tr("线程销毁完成");
}
测试效果: