线程类:QThread类
线程池:QThreadPool类
QMutex:
互斥锁;QReadWriteLock:
读-写锁;QSemaphore:
信号量;QWaitCondition:
条件变量。利用它们来保护线程间共享数据的完整性.
原子操作:QAtomicInteger、QAtomicPointer类,能够确保基础数据类型的读写操作的原子性。对于简单的计数、状态位的读写,使用原子操作类可以避免加锁开销。
在Qt框架中,qRegisterMetaType
这行代码的作用是向元对象系统注册自定义类型,使其能在跨线程信号槽(如队列连接 QueuedConnection
)中正确传递。
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//添加模板
qRegisterMetaType>("QVector");
MainWindow w;
w.show();
return a.exec();
}
UI:
方法一:
线程类:
.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include
#include
#include
///生成随机数
class MyThread : public QThread
{
Q_OBJECT
public:
explicit MyThread(QObject *parent = nullptr);
void run() override;
void setNum(int num);
signals:
void sendArray(QVector num);
private:
//循环次数
int m_num;
};
///冒泡排序
class BubbleSort : public QThread
{
Q_OBJECT
public:
explicit BubbleSort(QObject *parent = nullptr);
void run() override;
void setList(QVector list);
signals:
///处理完数据后发送处理的数组
void finish(QVector list);
private:
QVector m_list;
};
///快速排序
class QuickSort : public QThread
{
Q_OBJECT
public:
explicit QuickSort(QObject *parent = nullptr);
void run() override;
void setList(QVector list);
signals:
void finish(QVector list);
private:
// 分区函数(Lomuto分区方案)
void quickSort(QVector& arr, int low, int high) ;
int partition(QVector& arr, int low, int high);
QVector m_list;
};
#endif // MYTHREAD_H
.cpp
#include "mythread.h"
///QElapsedTimer:可以知道某个流程执行所用的时间
#include
#include
#include
MyThread::MyThread(QObject *parent) : QThread(parent)
{
}
void MyThread::run()
{
//QThread::currentThread():当前线程对象的地址
qDebug()<<"随机生成线程的地址:"< va;
QElapsedTimer time;
//生成随机数
//开始计时
time.start();
for(int i=0;i arr=m_list;
int n = arr.size();
bool swapped; // 优化标志位
for (int i = 0; i < n-1; ++i) {
swapped = false;
// 每次遍历将最大值"冒泡"到末尾
for (int j = 0; j < n-i-1; ++j) {
if (arr[j] > arr[j+1]) {
// 交换元素(使用std::swap更通用)
qSwap(arr[j], arr[j+1]);
swapped = true;
}
}
// 如果未发生交换,说明已有序,提前终止
if (!swapped) break;
}
int milse=time.elapsed();
qDebug()<<"冒泡线程的花费时间:"< list)
{
m_list=list;
}
QuickSort::QuickSort(QObject *parent):QThread(parent)
{
}
void QuickSort::run()
{
qDebug()<<"快速排序线程的地址:"<& arr, int low, int high)
{
// 随机选择基准元素(优化点)
int random = QRandomGenerator::global()->bounded(low, high);
qSwap(arr[random], arr[high]);
int pivot = arr[high];
int i = low - 1; // 指向小于基准的区域的末尾
for (int j = low; j <= high - 1; j++) {
if (arr[j] < pivot) {
i++;
qSwap(arr[i], arr[j]);
}
}
qSwap(arr[i + 1], arr[high]);
return i + 1;
}
// 快速排序递归实现
void QuickSort::quickSort(QVector& arr, int low, int high)
{
if (low < high) {
// pi 是分区后的基准位置
int pi = partition(arr, low, high);
// 递归排序左半部分和右半部分
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
void QuickSort::setList(QVector list)
{
m_list=list;
}
主函数调用:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "mythread.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//创建子线程对象
MyThread* my =new MyThread();
BubbleSort* bu=new BubbleSort();
QuickSort* qu=new QuickSort();
//设置随机数的个数
connect(this,&MainWindow::starting,my,&MyThread::setNum);
//按钮连接开启线程
connect(ui->pushButton,&QPushButton::clicked,this,[=](){
emit starting(10000);
my->start();
});
//接收子线程发送数据
connect(my,&MyThread::sendArray,bu,&BubbleSort::setList);
connect(my,&MyThread::sendArray,qu,&QuickSort::setList);
//接收子线程发送数据
connect(my,&MyThread::sendArray,this,[=](QVector list){
bu->start();
qu->start();
for (int i=0;ilistWidget_R->addItem(QString::number(list.at(i)));
}
});
//把处理好的数据显示到对应的UI控件上
connect(bu,&BubbleSort::finish,this,[=](QVector list){
for (int i=0;ilistWidget_B->addItem(QString::number(list.at(i)));
}
});
connect(qu,&QuickSort::finish,this,[=](QVector list){
for (int i=0;ilistWidget_Q->addItem(QString::number(list.at(i)));
}
});
}
MainWindow::~MainWindow()
{
delete ui;
}
方法二(推荐):
.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include
#include
#include
///生成随机数
class MyThread : public QObject
{
Q_OBJECT
public:
explicit MyThread(QObject *parent = nullptr);
void working(int num);
signals:
void sendArray(QVector num);
private:
};
///冒泡排序
class BubbleSort : public QObject
{
Q_OBJECT
public:
explicit BubbleSort(QObject *parent = nullptr);
void working(QVector m_list);
signals:
///处理完数据后发送处理的数组
void finish(QVector list);
private:
};
///快速排序
class QuickSort : public QObject
{
Q_OBJECT
public:
explicit QuickSort(QObject *parent = nullptr);
void working(QVector m_list);
signals:
void finish(QVector list);
private:
// 分区函数(Lomuto分区方案)
void quickSort(QVector& arr, int low, int high) ;
int partition(QVector& arr, int low, int high);
};
#endif // MYTHREAD_H
.cpp
#include "mythread.h"
///QElapsedTimer:可以知道某个流程执行所用的时间
#include
#include
#include
MyThread::MyThread(QObject *parent) : QObject(parent)
{
}
void MyThread::working(int m_num)
{
//QThread::currentThread():当前线程对象的地址
qDebug()<<"随机生成线程的地址:"< va;
QElapsedTimer time;
//生成随机数
//开始计时
time.start();
for(int i=0;i m_list)
{
qDebug()<<"冒泡线程的地址:"< arr=m_list;
int n = arr.size();
bool swapped; // 优化标志位
for (int i = 0; i < n-1; ++i) {
swapped = false;
// 每次遍历将最大值"冒泡"到末尾
for (int j = 0; j < n-i-1; ++j) {
if (arr[j] > arr[j+1]) {
// 交换元素(使用std::swap更通用)
qSwap(arr[j], arr[j+1]);
swapped = true;
}
}
// 如果未发生交换,说明已有序,提前终止
if (!swapped) break;
}
int milse=time.elapsed();
qDebug()<<"冒泡线程的花费时间:"< m_list)
{
qDebug()<<"快速排序线程的地址:"<& arr, int low, int high)
{
// 随机选择基准元素(优化点)
int random = QRandomGenerator::global()->bounded(low, high);
qSwap(arr[random], arr[high]);
int pivot = arr[high];
int i = low - 1; // 指向小于基准的区域的末尾
for (int j = low; j <= high - 1; j++) {
if (arr[j] < pivot) {
i++;
qSwap(arr[i], arr[j]);
}
}
qSwap(arr[i + 1], arr[high]);
return i + 1;
}
// 快速排序递归实现
void QuickSort::quickSort(QVector& arr, int low, int high)
{
if (low < high) {
// pi 是分区后的基准位置
int pi = partition(arr, low, high);
// 递归排序左半部分和右半部分
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
主函数调用:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "mythread.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//创建子线程对象
QThread* t1=new QThread();
QThread* t2=new QThread();
QThread* t3=new QThread();
//不能添加父对象
MyThread* my =new MyThread();
BubbleSort* bu=new BubbleSort();
QuickSort* qu=new QuickSort();
//将任务对象移动到子线程中
my->moveToThread(t1);
bu->moveToThread(t2);
qu->moveToThread(t3);
//设置随机数的个数
connect(this,&MainWindow::starting,my,&MyThread::working);
//按钮连接开启线程
connect(ui->pushButton,&QPushButton::clicked,this,[=](){
emit starting(10000);
t1->start();
});
//接收子线程发送数据
connect(my,&MyThread::sendArray,bu,&BubbleSort::working);
connect(my,&MyThread::sendArray,qu,&QuickSort::working);
//接收子线程发送数据
connect(my,&MyThread::sendArray,this,[=](QVector list){
t2->start();
t3->start();
for (int i=0;ilistWidget_R->addItem(QString::number(list.at(i)));
}
});
//把处理好的数据显示到对应的UI控件上
connect(bu,&BubbleSort::finish,this,[=](QVector list){
for (int i=0;ilistWidget_B->addItem(QString::number(list.at(i)));
}
});
connect(qu,&QuickSort::finish,this,[=](QVector list){
for (int i=0;ilistWidget_Q->addItem(QString::number(list.at(i)));
}
});
}
MainWindow::~MainWindow()
{
delete ui;
}
释放资源:
第一种:
//创建子线程对象
QThread* t1=new QThread(this);
QThread* t2=new QThread(this);
QThread* t3=new QThread(this);
第二种:
///&MainWindow::destroyed信号:当前窗口析构时会触发信号
connect(this,&MainWindow::destroyed,this,[=](){
///释放资源
t1->quit();
t1->wait();
t1->deleteLater();//等价于 delete t1;
///释放资源
bu->deleteLater();
});
线程池:
#include
#include
#include
#include
///生成随机数
class MyThread : public QObject, public QRunnable
{
Q_OBJECT
public:
explicit MyThread(QObject *parent = nullptr);
void run() override;
void setNum(int num);
signals:
void sendArray(QVector num);
private:
//循环次数
int m_num;
};
.cpp
MyThread::MyThread(QObject *parent) : QObject(parent), QRunnable()
{
//放入线程池后自动析构
setAutoDelete(true);
}
void MyThread::run()
{
//QThread::currentThread():当前线程对象的地址
qDebug()<<"随机生成线程的地址:"< va;
QElapsedTimer time;
//生成随机数
//开始计时
time.start();
for(int i=0;isetupUi(this);
//创建子线程对象
MyThread* my =new MyThread();
BubbleSort* bu=new BubbleSort();
QuickSort* qu=new QuickSort();
//设置随机数的个数
connect(this,&MainWindow::starting,my,&MyThread::setNum);
//按钮连接开启线程
connect(ui->pushButton,&QPushButton::clicked,this,[=](){
emit starting(10000);
//加入到线程池并开启
QThreadPool::globalInstance()->start(my);
});
//接收子线程发送数据
connect(my,&MyThread::sendArray,bu,&BubbleSort::setList);
connect(my,&MyThread::sendArray,qu,&QuickSort::setList);
//接收子线程发送数据
connect(my,&MyThread::sendArray,this,[=](QVector list){
QThreadPool::globalInstance()->start(bu);
QThreadPool::globalInstance()->start(qu);
for (int i=0;ilistWidget_R->addItem(QString::number(list.at(i)));
}
});
//把处理好的数据显示到对应的UI控件上
connect(bu,&BubbleSort::finish,this,[=](QVector list){
for (int i=0;ilistWidget_B->addItem(QString::number(list.at(i)));
}
});
connect(qu,&QuickSort::finish,this,[=](QVector list){
for (int i=0;ilistWidget_Q->addItem(QString::number(list.at(i)));
}
});
}