Qt多线程
1,构造函数
// 构造函数
QThread::QThread(QObject *parent = Q_NULLPTR);
// 判断线程中的任务是不是处理完毕了
bool QThread::isFinished() const;
// 判断子线程是不是在执行任务
bool QThread::isRunning() const;
// Qt中的线程可以设置优先级
// 得到当前线程的优先级
Priority QThread::priority() const;
void QThread::setPriority(Priority priority);
优先级:
QThread::IdlePriority --> 最低的优先级
QThread::LowestPriority
QThread::LowPriority
QThread::NormalPriority
QThread::HighPriority
QThread::HighestPriority
QThread::TimeCriticalPriority --> 最高的优先级
QThread::InheritPriority --> 子线程和其父线程的优先级相同, 默认是这个
// 退出线程, 停止底层的事件循环
// 退出线程的工作函数
oid QThread::exit(int returnCode = 0);
// 调用线程退出函数之后, 线程不会马上退出因为当前任务有可能还没有完成, 调回用这个函数是
// 等待任务完成, 然后退出线程, 一般情况下会在 exit() 后边调用这个函数
bool QThread::wait(unsigned long time = ULONG_MAX);信号槽
// 和调用 exit() 效果是一样的
[slot] void QThread::quit();
// 启动子线程
[slot] void QThread::start(Priority priority = InheritPriority);
// 线程中执行的任务完成了, 发出该信号
// 任务函数中的处理逻辑执行完毕了
[signal] void QThread::finished();
// 开始工作之前发出这个信号, 一般不使用
[signal] void QThread::started();静态函数
// 返回一个指向管理当前执行线程的QThread的指针
[static] QThread *QThread::currentThread();
// 返回可以在系统上运行的理想线程数 == 和当前电脑的 CPU 核心数相同
[static] int QThread::idealThreadCount();
// 线程休眠函数
[static] void QThread::msleep(unsigned long msecs); // 单位: 毫秒
[static] void QThread::sleep(unsigned long secs); // 单位: 秒
[static] void QThread::usleep(unsigned long usecs); // 单位: 微秒任务处理
// 子线程要处理什么任务, 需要写到 run() 中
[virtual protected] void QThread::run();2,任务对象移动到主线程
线程头文件
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QObject>
#include <QVector>
//创建的子线程,生成随机数
class Generate : public QObject
{
Q_OBJECT
public:
explicit Generate(QObject *parent = nullptr);
//接受主线程传过来的参数,随机数num
//子线程运行函数,第二种方法可以直接将num作为参数传入
void working(int num);
signals:
//使用信号槽将数据传递给主线程,界面操作只能由主线程来进行
void sendArray(QVector<int> num);
public slots:
};
//冒泡排序
class BubbleSort : public QObject
{
Q_OBJECT
public:
explicit BubbleSort(QObject *parent = nullptr);
//子线程运行函数
void working(QVector<int> list);
signals:
//使用信号槽将数据传递给主线程,界面操作只能由主线程来进行
//发送的有序数组
void finish(QVector<int> list);
public slots:
};
//快速排序
class QuickSort : public QObject
{
Q_OBJECT
public:
explicit QuickSort(QObject *parent = nullptr);
//子线程运行函数
void working(QVector<int> list);
signals:
//使用信号槽将数据传递给主线程,界面操作只能由主线程来进行
void finish(QVector<int> list);
public slots:
private:
//实现快速排序算法
//容器,起始位置,结束位置
void quickSort(QVector<int> &list,int l,int r);
};
#endif // MYTHREAD_H线程实现
#include "mythread.h"
#include <QElapsedTimer> //记录时间
#include <QtDebug>
#include <QThread>
Generate::Generate(QObject *parent) : QObject(parent)
{
}
void Generate::working(int num)
{
qDebug()<< "生成随机数的线程地址" <<QThread::currentThread();
//存放随机数vector容器
QVector<int> list; //子线程生成数据,要通过传递给主线程
QElapsedTimer time;
time.start();//开始记录
for (int i = 0;i <num;++i)
{
//从尾部插入
list.push_back(qrand()%100000);
}
qint64 milsec = time.elapsed(); //毫秒
qDebug()<< "生成" <<num << "个随机总数用时"<<milsec<<"毫秒";
//发送给主线程
emit sendArray(list); //将数据发给主线程
}
//冒泡排序,补齐parent
BubbleSort::BubbleSort(QObject *parent) : QObject(parent)
{
}
//实现冒泡排序,实现相邻两个元素的交换
void BubbleSort::working(QVector<int> list)
{
qDebug()<< "冒泡排序的线程地址" <<QThread::currentThread();
//存放随机数vector容器
QElapsedTimer time;
time.start();
int temp;
for(int i = 0;i<list.size();++i)
{
for(int j =0;j<list.size()-i-1;++j) //从后数往前比较
{
if(list[j]>list[j+1])
{
temp = list[j];
list[j] = list[j+1];
list[j+1]=temp;
}
}
}
qint64 milsec = time.elapsed();
qDebug()<< "冒泡排序用时" <<milsec<<"毫秒";
//发送给主线程
emit finish(list); //将数据发给主线程
}
//快速,补齐parent
QuickSort::QuickSort(QObject *parent) : QObject(parent)
{
}
//实现快速排序
void QuickSort::working(QVector<int> list)
{
qDebug()<< "快速排序的线程地址" <<QThread::currentThread();
//存放随机数vector容器
QElapsedTimer time;
time.start();
//快速排序算法
quickSort(list,0,list.size()-1);
qint64 milsec = time.elapsed();
qDebug()<< "快速排序用时" <<milsec<<"毫秒";
//发送给主线程
emit finish(list); //将数据发给主线程
}
//快排算法
void QuickSort::quickSort(QVector<int> &s, int l, int r)
{
if(l < r)
{
int i = l,j=r;
//拿出第一个元素,保存到x中,第一个位置为空
int x = s[l];
while (i < j)
{
// 从右向左找小于x的数
while (i < j && s[j] >= x)
{
//左移, 直到遇到小于等于x的数
j--;
}
if (i < j)
{
//将右侧找到的小于x的元素放入左侧坑中, 右侧出现一个坑
//左侧元素索引后移
s[i++] = s[j];
}
// 从左向右找大于等于x的数
while (i < j && s[i] < x)
{
//右移, 直到遇到大于x的数
i++;
}
if (i < j)
{
//将左侧找到的元素放入右侧坑中, 左侧出现一个坑
//右侧元素索引向前移动
s[j--] = s[i];
}
}
//此时 i=j,将保存在x中的数填入坑中
s[i] = x;
quickSort(s, l, i - 1); // 递归调用
quickSort(s, i + 1, r);
}
}线程调用
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "mythread.h"
#include <QThread>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//当运行,用户点击按钮,就要调用子线程生成随机数,传递给主线程
//1,创建子线程对象,
// QThread* t1 = new QThread(this); //添加之后会析构申请的空间
// QThread* t2 = new QThread(this);
// QThread* t3 = new QThread(this);
QThread* t1 = new QThread;
QThread* t2 = new QThread;
QThread* t3 = new QThread;
//2,创建任务类的对象
Generate* gen = new Generate;
BubbleSort * bubble = new BubbleSort;
QuickSort * quick = new QuickSort;
//3,将任务对象移动到某个子线程中
gen->moveToThread(t1); //生成随机数
bubble->moveToThread(t2);
quick->moveToThread(t3);
//信号和槽,主函数将starting的数,传递给子线程的recNum用户接受数量
connect(this,&MainWindow::starting,gen,&Generate::working);
//启动子线程,使用信号与槽,当用户点击
connect(ui->start,&QPushButton::clicked,this,[=]()
{
emit starting(10000);
//给子线程发送信号
t1->start(); //调用子线程运行方法,还没有执行
});
//当有了随机数之后,开始起痘冒泡和快速排序线程
//在排序之前,线程要先拿到所需要的数据
connect(gen,&Generate::sendArray,bubble,&BubbleSort::working);
connect(gen,&Generate::sendArray,quick,&QuickSort::working);
//添加connect用于接受子线程传过来的list容器随机数
//连接子线程,但子线程信号sendArray运行时,主线程接受
connect(gen,&Generate::sendArray,this,[=](QVector <int> list)
{
//
//主线程开始接受来自子线程发送过来的list,于此同时子线程开始运行
t2->start();
t3->start();
for(int i =0;i<list.size();i++)
{
ui->randlist->addItem(QString::number(list.at(i)));
}
});
//排序运行之后,将排序好的数据放到主线程
connect(bubble,&BubbleSort::finish,this,[=](QVector<int> list)
{
for(int i =0;i<list.size();++i)
{
ui->bubblelist->addItem(QString::number(list.at(i)));
}
});
connect(quick,&QuickSort::finish,this,[=](QVector<int> list)
{
for(int i =0;i<list.size();++i)
{
ui->quicklist->addItem(QString::number(list.at(i)));
}
});
//手写销毁资源
connect(this,&MainWindow::destroy,this,[=]()
{
t1->quit();
t1->wait();
t1->deleteLater(); //释放空间
t2->quit();
t2->wait();
t2->deleteLater(); //释放空间
t3->quit();
t3->wait();
t3->deleteLater(); //释放空间
gen->deleteLater();
bubble->deleteLater();
quick->deleteLater();
});
}
MainWindow::~MainWindow()
{
delete ui;
}3,线程池
创建子线程
- 引用头文件
#include <QRunnable>
#include <QVector>
#include <QObject>头文件
//创建的子线程,生成随机数
class Generate : public QObject, public QRunnable
{
Q_OBJECT
public:
explicit Generate(QObject *parent = nullptr);
//接受主线程传过来的参数,随机数num
void recNum(int num);
//子线程运行函数
void run() override;
signals:
//使用信号槽将数据传递给主线程,界面操作只能由主线程来进行
void sendArray(QVector<int> num);
public slots:
private:
//设置信号槽接受主线程传过来的数据
int m_num;
};
//冒泡排序
class BubbleSort : public QObject, public QRunnable
{
Q_OBJECT
public:
explicit BubbleSort(QObject *parent = nullptr);
//接受主线程传过来的参数,数组
void recArray(QVector<int> list);
//子线程运行函数
void run() override;
signals:
//使用信号槽将数据传递给主线程,界面操作只能由主线程来进行
//发送的有序数组
void finish(QVector<int> list);
public slots:
private:
//设置信号槽接受主线程传过来的数据
QVector<int> m_list;
};
//快速排序
class QuickSort : public QObject, public QRunnable
{
Q_OBJECT
public:
explicit QuickSort(QObject *parent = nullptr);
//接受主线程传过来的参数,随机数num
void recArray(QVector<int> list);
//子线程运行函数
void run() override;
signals:
//使用信号槽将数据传递给主线程,界面操作只能由主线程来进行
void finish(QVector<int> list);
private:
//设置信号槽接受主线程传过来的数据
QVector<int> m_list;
//实现快速排序算法
//容器,起始位置,结束位置
void quickSort(QVector<int> &list,int l,int r);
};函数实现
#include "mythread.h"
#include <QElapsedTimer> //记录时间
#include <QtDebug>
#include <QThread>
Generate::Generate(QObject *parent) : QObject(parent),QRunnable()
{
setAutoDelete(true);
}
void Generate::recNum(int num)
{
m_num = num;
}
void Generate::run()
{
qDebug()<< "生成随机数的线程地址" <<QThread::currentThread();
//存放随机数vector容器
QVector<int> list; //子线程生成数据,要通过传递给主线程
QElapsedTimer time;
time.start();//开始记录
for (int i = 0;i < m_num;++i)
{
//从尾部插入
list.push_back(qrand()%100000);
}
qint64 milsec = time.elapsed(); //毫秒
qDebug()<< "生成" <<m_num << "个随机总数用时"<<milsec<<"毫秒";
//发送给主线程
emit sendArray(list); //将数据发给主线程
}
//冒泡排序,补齐parent
BubbleSort::BubbleSort(QObject *parent) : QObject(parent),QRunnable()
{
setAutoDelete(true);
}
//接受传递的vector变量
void BubbleSort::recArray(QVector<int> list)
{
m_list = list;
}
//实现冒泡排序,实现相邻两个元素的交换
void BubbleSort::run()
{
qDebug()<< "冒泡排序的线程地址" <<QThread::currentThread();
//存放随机数vector容器
QElapsedTimer time;
time.start();
int temp;
for(int i = 0;i<m_list.size();++i)
{
for(int j =0;j<m_list.size()-i-1;++j) //从后数往前比较
{
if(m_list[j]>m_list[j+1])
{
temp = m_list[j];
m_list[j] = m_list[j+1];
m_list[j+1]=temp;
}
}
}
qint64 milsec = time.elapsed();
qDebug()<< "冒泡排序用时" <<milsec<<"毫秒";
//发送给主线程
emit finish(m_list); //将数据发给主线程
}
//快速,补齐parent
QuickSort::QuickSort(QObject *parent) : QObject(parent),QRunnable()
{
setAutoDelete(true); //自动释放空间
}
//接受传递的vector变量
void QuickSort::recArray(QVector<int> list)
{
m_list = list;
}
//实现快速排序
void QuickSort::run()
{
qDebug()<< "快速排序的线程地址" <<QThread::currentThread();
//存放随机数vector容器
QElapsedTimer time;
time.start();
//快速排序算法
quickSort(m_list,0,m_list.size()-1);
qint64 milsec = time.elapsed();
qDebug()<< "快速排序用时" <<milsec<<"毫秒";
//发送给主线程
emit finish(m_list); //将数据发给主线程
}
//快排算法
void QuickSort::quickSort(QVector<int> &s, int l, int r)
{
if(l < r)
{
int i = l,j=r;
//拿出第一个元素,保存到x中,第一个位置为空
int x = s[l];
while (i < j)
{
// 从右向左找小于x的数
while (i < j && s[j] >= x)
{
//左移, 直到遇到小于等于x的数
j--;
}
if (i < j)
{
//将右侧找到的小于x的元素放入左侧坑中, 右侧出现一个坑
//左侧元素索引后移
s[i++] = s[j];
}
// 从左向右找大于等于x的数
while (i < j && s[i] < x)
{
//右移, 直到遇到大于x的数
i++;
}
if (i < j)
{
//将左侧找到的元素放入右侧坑中, 左侧出现一个坑
//右侧元素索引向前移动
s[j--] = s[i];
}
}
//此时 i=j,将保存在x中的数填入坑中
s[i] = x;
quickSort(s, l, i - 1); // 递归调用
quickSort(s, i + 1, r);
}
}主函数调用
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "mythread.h"
#include <QThreadPool>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//当运行,用户点击按钮,就要调用子线程生成随机数,传递给主线程
//创建任务类对象
Generate* gen = new Generate;
BubbleSort * bubble = new BubbleSort;
QuickSort * quick = new QuickSort;
//信号和槽,主函数将starting的数,传递给子线程的recNum用户接受数量
connect(this,&MainWindow::starting,gen,&Generate::recNum);
//启动子线程,使用信号与槽,当用户点击
connect(ui->start,&QPushButton::clicked,this,[=]()
{
emit starting(10000);
//给子线程发送信号
QThreadPool::globalInstance()->start(gen); //线程池中运行
});
//当有了随机数之后,开始起痘冒泡和快速排序线程
//在排序之前,线程要先拿到所需要的数据
connect(gen,&Generate::sendArray,bubble,&BubbleSort::recArray);
connect(gen,&Generate::sendArray,quick,&QuickSort::recArray);
//添加connect用于接受子线程传过来的list容器随机数
//连接子线程,但子线程信号sendArray运行时,主线程接受
connect(gen,&Generate::sendArray,this,[=](QVector <int> list)
{
//
//主线程开始接受来自子线程发送过来的list,于此同时子线程开始运行
QThreadPool::globalInstance()->start(bubble); //线程池中运行
QThreadPool::globalInstance()->start(quick); //线程池中运行
for(int i =0;i<list.size();i++)
{
ui->randlist->addItem(QString::number(list.at(i)));
}
});
//排序运行之后,将排序好的数据放到主线程
connect(bubble,&BubbleSort::finish,this,[=](QVector<int> list)
{
for(int i =0;i<list.size();++i)
{
ui->bubblelist->addItem(QString::number(list.at(i)));
}
});
connect(quick,&QuickSort::finish,this,[=](QVector<int> list)
{
for(int i =0;i<list.size();++i)
{
ui->quicklist->addItem(QString::number(list.at(i)));
}
});
}
MainWindow::~MainWindow()
{
delete ui;
}
4,线程
头文件
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
#include <QVector>
//创建的子线程,生成随机数
class Generate : public QThread
{
Q_OBJECT
public:
explicit Generate(QObject *parent = nullptr);
//接受主线程传过来的参数,随机数num
void recNum(int num);
protected:
//子线程运行函数
void run() override;
signals:
//使用信号槽将数据传递给主线程,界面操作只能由主线程来进行
void sendArray(QVector<int> num);
public slots:
private:
//设置信号槽接受主线程传过来的数据
int m_num;
};
//冒泡排序
class BubbleSort : public QThread
{
Q_OBJECT
public:
explicit BubbleSort(QObject *parent = nullptr);
//接受主线程传过来的参数,数组
void recArray(QVector<int> list);
protected:
//子线程运行函数
void run() override;
signals:
//使用信号槽将数据传递给主线程,界面操作只能由主线程来进行
//发送的有序数组
void finish(QVector<int> list);
public slots:
private:
//设置信号槽接受主线程传过来的数据
QVector<int> m_list;
};
//快速排序
class QuickSort : public QThread
{
Q_OBJECT
public:
explicit QuickSort(QObject *parent = nullptr);
//接受主线程传过来的参数,随机数num
void recArray(QVector<int> list);
protected:
//子线程运行函数
void run() override;
signals:
//使用信号槽将数据传递给主线程,界面操作只能由主线程来进行
void finish(QVector<int> list);
public slots:
private:
//设置信号槽接受主线程传过来的数据
QVector<int> m_list;
//实现快速排序算法
//容器,起始位置,结束位置
void quickSort(QVector<int> &list,int l,int r);
};
#endif // MYTHREAD_H函数实现
#include "mythread.h"
#include <QElapsedTimer> //记录时间
#include <QtDebug>
Generate::Generate(QObject *parent) : QThread(parent)
{
}
void Generate::recNum(int num)
{
m_num = num;
}
void Generate::run()
{
qDebug()<< "生成随机数的线程地址" <<QThread::currentThread();
//存放随机数vector容器
QVector<int> list; //子线程生成数据,要通过传递给主线程
QElapsedTimer time;
time.start();//开始记录
for (int i = 0;i < m_num;++i)
{
//从尾部插入
list.push_back(qrand()%100000);
}
qint64 milsec = time.elapsed(); //毫秒
qDebug()<< "生成" <<m_num << "个随机总数用时"<<milsec<<"毫秒";
//发送给主线程
emit sendArray(list); //将数据发给主线程
}
//冒泡排序,补齐parent
BubbleSort::BubbleSort(QObject *parent) : QThread(parent)
{
}
//接受传递的vector变量
void BubbleSort::recArray(QVector<int> list)
{
m_list = list;
}
//实现冒泡排序,实现相邻两个元素的交换
void BubbleSort::run()
{
qDebug()<< "冒泡排序的线程地址" <<QThread::currentThread();
//存放随机数vector容器
QElapsedTimer time;
time.start();
int temp;
for(int i = 0;i<m_list.size();++i)
{
for(int j =0;j<m_list.size()-i-1;++j) //从后数往前比较
{
if(m_list[j]>m_list[j+1])
{
temp = m_list[j];
m_list[j] = m_list[j+1];
m_list[j+1]=temp;
}
}
}
qint64 milsec = time.elapsed();
qDebug()<< "冒泡排序用时" <<milsec<<"毫秒";
//发送给主线程
emit finish(m_list); //将数据发给主线程
}
//快速,补齐parent
QuickSort::QuickSort(QObject *parent) : QThread(parent)
{
}
//接受传递的vector变量
void QuickSort::recArray(QVector<int> list)
{
m_list = list;
}
//实现快速排序
void QuickSort::run()
{
qDebug()<< "快速排序的线程地址" <<QThread::currentThread();
//存放随机数vector容器
QElapsedTimer time;
time.start();
//快速排序算法
quickSort(m_list,0,m_list.size()-1);
qint64 milsec = time.elapsed();
qDebug()<< "快速排序用时" <<milsec<<"毫秒";
//发送给主线程
emit finish(m_list); //将数据发给主线程
}
//快排算法
void QuickSort::quickSort(QVector<int> &s, int l, int r)
{
if(l < r)
{
int i = l,j=r;
//拿出第一个元素,保存到x中,第一个位置为空
int x = s[l];
while (i < j)
{
// 从右向左找小于x的数
while (i < j && s[j] >= x)
{
//左移, 直到遇到小于等于x的数
j--;
}
if (i < j)
{
//将右侧找到的小于x的元素放入左侧坑中, 右侧出现一个坑
//左侧元素索引后移
s[i++] = s[j];
}
// 从左向右找大于等于x的数
while (i < j && s[i] < x)
{
//右移, 直到遇到大于x的数
i++;
}
if (i < j)
{
//将左侧找到的元素放入右侧坑中, 左侧出现一个坑
//右侧元素索引向前移动
s[j--] = s[i];
}
}
//此时 i=j,将保存在x中的数填入坑中
s[i] = x;
quickSort(s, l, i - 1); // 递归调用
quickSort(s, i + 1, r);
}
}函数调用
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "mythread.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//当运行,用户点击按钮,就要调用子线程生成随机数,传递给主线程
//创建子线程对象,
Generate* gen = new Generate;
BubbleSort * bubble = new BubbleSort;
QuickSort * quick = new QuickSort;
//信号和槽,主函数将starting的数,传递给子线程的recNum用户接受数量
connect(this,&MainWindow::starting,gen,&Generate::recNum);
//启动子线程,使用信号与槽,当用户点击
connect(ui->start,&QPushButton::clicked,this,[=]()
{
emit starting(10000);
//给子线程发送信号
gen->start(); //调用子线程运行方法
});
//当有了随机数之后,开始起痘冒泡和快速排序线程
//在排序之前,线程要先拿到所需要的数据
connect(gen,&Generate::sendArray,bubble,&BubbleSort::recArray);
connect(gen,&Generate::sendArray,quick,&QuickSort::recArray);
//添加connect用于接受子线程传过来的list容器随机数
//连接子线程,但子线程信号sendArray运行时,主线程接受
connect(gen,&Generate::sendArray,this,[=](QVector <int> list)
{
//
//主线程开始接受来自子线程发送过来的list,于此同时子线程开始运行
bubble->start();
quick->start();
for(int i =0;i<list.size();i++)
{
ui->randlist->addItem(QString::number(list.at(i)));
}
});
//排序运行之后,将排序好的数据放到主线程
connect(bubble,&BubbleSort::finish,this,[=](QVector<int> list)
{
for(int i =0;i<list.size();++i)
{
ui->bubblelist->addItem(QString::number(list.at(i)));
}
});
connect(quick,&QuickSort::finish,this,[=](QVector<int> list)
{
for(int i =0;i<list.size();++i)
{
ui->quicklist->addItem(QString::number(list.at(i)));
}
});
connect(this,&MainWindow::destroyed,this,[=]()
{
gen->quit();
gen->wait();
gen->deleteLater(); //释放空间
bubble->quit();
bubble->wait();
bubble->deleteLater(); //释放空间
quick->quit();
quick->wait();
quick->deleteLater(); //释放空间
});
}
MainWindow::~MainWindow()
{
delete ui;
}