Qt创建线程(线程池)

news2024/11/19 3:15:40

1.线程池可以创建线程统一的管理线程(统一创建、释放线程)

2.使用线程池方法实现点击开始按钮生成10000个随机数,然后分别使用冒泡排序和快速排序排序这10000个随机数,最后在窗口显示排序后的数字:

mainwindow.h文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
signals:
    void starting(int num);
private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

mythread.h文件:

#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QObject>
#include <QRunnable>
//生成随机数
class MyThread : public QObject,public QRunnable //要使用Qt的信号槽继承就必须要继承QObject类(实现多继承)(注意QObject类要写在前面)
{
    Q_OBJECT
public:
    explicit MyThread(QObject *parent = nullptr);
    void recvNum(int num);
    void run() override;
signals:
    void sendArray(QVector<int> list);
private:
    int m_num;
};

class BubbleSort : public QObject,public QRunnable
{
    Q_OBJECT
public:
    explicit BubbleSort(QObject *parent = nullptr);
    void recvArray(QVector<int> list);
    void run() override;
signals:
    void finish(QVector<int> num);
private:
    QVector<int> m_list;
};

class QuickSort : public QObject,public QRunnable
{
    Q_OBJECT
public:
    explicit QuickSort(QObject *parent = nullptr);
    void recvArray(QVector<int> list);
private:
    void quickSort(QVector<int> &list, int l, int r);
    void run() override;
signals:
    void finish(QVector<int> num);
private:
    QVector<int> m_list;

};
#endif // MYTHREAD_H

main.cpp 

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    qRegisterMetaType<QVector<int>>("QVector<int>");
    MainWindow w;
    w.show();
    return a.exec();
}

mainwindow.cpp

#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);
    //1.创建任务类对象
    MyThread *gen = new MyThread;
    BubbleSort *bubble = new BubbleSort;
    QuickSort *quick = new QuickSort;
    connect(this, &MainWindow::starting, gen, &MyThread::recvNum);
    //2.启动子线程
    connect(ui->start, &QPushButton::clicked, this, [=]{
        emit starting(10000); //在启动子线程时,将要生成的随机数的个数发送出去
        QThreadPool::globalInstance()->start(gen); //将任务类对象(生成随机数)丢到线程池中


    });
    //接收子线程发送的数据
    connect(gen, &MyThread::sendArray, bubble, &BubbleSort::recvArray);
    connect(gen, &MyThread::sendArray, quick, &QuickSort::recvArray);
    connect(gen, &MyThread::sendArray, this, [=](QVector<int> list){ //connect里面不支持传递QVector类型//需要使用qRegisterMetaType()进行注册
       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){ //connect里面不支持传递QVector类型//需要使用qRegisterMetaType()进行注册
        for(int i = 0; i < list.size(); i++){
            ui->bubbleList->addItem(QString::number(list.at(i)));
        }
    });
    connect(quick, &QuickSort::finish, this, [=](QVector<int> list){ //connect里面不支持传递QVector类型//需要使用qRegisterMetaType()进行注册
        for(int i = 0; i < list.size(); i++){
            ui->quickList->addItem(QString::number(list.at(i)));
        }
    });
    \
}


MainWindow::~MainWindow()
{
    delete ui;
}

 mythread.cpp文件:

#include "mythread.h"
#include <QVector>
#include <QElapsedTimer> //计算某个流程执行所使用的时间
#include <QDebug>
#include <QThread>

MyThread::MyThread(QObject *parent)
    : QObject(parent), QRunnable()
{
    setAutoDelete(true); //设置当前这个线程的对象放到线程池里后,在工作完毕后自动释放
}

void MyThread::recvNum(int num)
{
    m_num = num;
}

void MyThread::run()
{
    qDebug() << "生成随机数的线程地址" << QThread::currentThread(); //获取一个指针,这个指针指向当前线程对象的地址
    QVector<int> list;
    QElapsedTimer time;
    time.start();
    for(int i = 0; i < m_num; i++){
        list.push_back(qrand() % 100000);
    }
    int milsec = time.elapsed();
    qDebug() << "生成" << m_num << "个随机数总共用时:" << milsec << "毫秒";
    emit sendArray(list);
}

BubbleSort::BubbleSort(QObject *parent)
    : QObject(parent), QRunnable()
{
    setAutoDelete(true); //设置当前这个线程的对象放到线程池里后,在工作完毕后自动释放
}


void BubbleSort::recvArray(QVector<int> list)
{
    m_list = list;
}

void BubbleSort::run()
{
    qDebug() << "冒泡排序的线程地址" << QThread::currentThread(); //获取一个指针,这个指针指向当前线程对象的地址
    QElapsedTimer time;
    time.start();
    for(int i = 0; i < m_list.size() - 1 ;i++){
        for(int j = 0;j < m_list.size() - i - 1; j++){
            if(m_list[j] > m_list[j + 1]){
                int temp = m_list[j];
                m_list[j] = m_list[j + 1];
                m_list[j + 1] = temp;
            }
        }
    }
    int milsec = time.elapsed();
    qDebug() << "冒泡排序用时" << milsec << "毫秒";
    emit finish(m_list);
}

QuickSort::QuickSort(QObject *parent)
    : QObject(parent), QRunnable()
{
    setAutoDelete(true); //设置当前这个线程的对象放到线程池里后,在工作完毕后自动释放
}


void QuickSort::recvArray(QVector<int> list)
{
    m_list = list;
}

void QuickSort::quickSort(QVector<int> &s, int l, int r)
{
    if(l < r){
        int i = l, j = r;
        int x = s[l];
        while(i < j){
            while(i < j &&s[j] >=x){
                j--;
            }
            if(i < j){
                s[i++] = s[j];
            }
            while(i < j && s[i] < x){
                i++;
            }
            if(i < j){
                s[j--] = s[i];
            }
        }
        s[i] = x;
        quickSort(s, l, i - 1);
        quickSort(s, i + 1, r);
    }
}

void QuickSort::run()
{
    qDebug() << "快速排序的线程地址" << QThread::currentThread(); //获取一个指针,这个指针指向当前线程对象的地址
    QElapsedTimer time;
    time.start();
    quickSort(m_list, 0,m_list.size()-1);
    int milsec = time.elapsed();
    qDebug() << "快速排序用时" << milsec << "毫秒";
            emit finish(m_list);
}

运行结果:

        通过运行结果可以发现:生成随机数的线程和冒泡排序的线程是使用线程池中的同一个线程,生成随机数的线程结束后就空闲了,然后又来了两个任务冒泡排序和快速排序,所以就又使用了这个空闲的任务来运行冒泡排序,然后快速排序用到了线程池里面的另一个线程。通过这点可以知道:通过线程池可以最大程度利用线程,减少资源的浪费。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1032282.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CATIA | 如何创建曲面点云数据并保存

问题描述 CATIA中创建的曲面模型&#xff0c;如何转换成可读的点云数据&#xff08;点云坐标数据&#xff09;输出保存&#xff1b; 操作流程&#xff08;示例&#xff09; 1、打开软件 2、创建三维曲面模型 &#xff08;具体步骤省略&#xff09; 3、文件另存为“.stl” …

wallet connect简单使用

wallet connect简单使用 准备工作安装配置打包测试 准备工作 新建一个文件夹xxx 右键在终端中打开 npm init -y在文件夹中新建src目录 在src目录中新建index.html和index.js文件 目录大概就这样我这是打包过的 安装 按照官方文档先安装 官方页面长这样 我们需要用到的是we…

基于Dijkstra、A*和动态规划的移动机器人路径规划(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑…

【软件设计师-中级——刷题记录3(纯干货)】

目录 数据交换模式知识产权与标准化之侵权判断OSI专业模型&#xff1a;7-克制自己的同理心8-不要为不值得的人和事浪费时间9-做个长期主义者 每日一言&#xff1a;持续更新中... 个人昵称&#xff1a;lxw-pro 个人主页&#xff1a;欢迎关注 我的主页 个人感悟&#xff1a; “失…

20 mysql const 查询

前言 这里主要是 探究一下 explain $sql 中各个 type 诸如 const, ref, range, index, all 的查询的影响, 以及一个初步的效率的判断 这里会调试源码来看一下 各个类型的查询 需要 lookUp 的记录 以及 相关的差异 测试表结构信息如下 CREATE TABLE tz_test (id int(1…

基于SpringBoot的蜗牛兼职网站

目录 前言 一、技术栈 二、系统功能介绍 管理员功能模块 用户功能模块 前台首页功能模块 企业功能模块 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#x…

接口测试之什么是接口文档?

一、为什么要有接口文档&#xff1f; 没有接口文档的接口测试都是在抓瞎~前面的接口测试重点讲了协议&#xff0c;也讲了fiddler模拟接口请求&#xff0c;估计大部分还是不太懂怎么下手测试。这里小编专门拿出接口文档来做接口测试参考&#xff08;估计很多测试小伙伴没见过接口…

GDB的TUI模式(文本界面)

2023年9月22日&#xff0c;周五晚上 今晚在看GDB的官方文档时&#xff0c;发现GDB居然有文本界面模式 TUI (Debugging with GDB) (sourceware.org) GDB开启TUI的条件 GDB的文本界面的开启条件是&#xff1a;操作系统有适当版本的curses库 The TUI mode is supported only on…

期刊分类一览

分区情况 jcr分区 中科院分区 EI 理工科 一般是SCI的都是EI 国内的分区

基于eBPF的安卓逆向辅助工具——stackplz

前言 stackplz是一款基于eBPF技术实现的追踪工具&#xff0c;目的是辅助安卓native逆向&#xff0c;仅支持64位进程&#xff0c;主要功能如下&#xff1a; hardware breakpoint 基于pref_event实现的硬件断点功能&#xff0c;在断点处可读取寄存器信息&#xff0c;不会被用户…

【计算机网络】子网掩码、子网划分

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; 更多计算机网络知识专栏&#xff1a;计算机网络&#x1f525; 给大家跳段…

为什么曲面函数的偏导数可以表示其曲面的法向量?

为什么曲面函数的偏导数可以表示其曲面的法向量&#xff1f; 引用资料&#xff1a; 1.知乎shinbade&#xff1a;曲面的三个偏导数为什么能表示法向量&#xff1f; 2.Geogebra羅驥韡 (Pegasus Roe)&#xff1a;偏導數、切平面、梯度 曲面 F ( x , y , z ) 0 F(x,y,z)0 F(x,y,…

Direct3D模板缓存

模板缓存是一个用于获得某种特效的离屏缓存&#xff0c;模板缓存的分辨率与后台缓存和深度缓存的分辨率完全相同&#xff0c;所以像素也是一一对应的&#xff0c;模板缓存允许我们动态的&#xff0c;有针对性的决定是否将某个像素写入后台缓存中。 例如实现镜面效果时&#xf…

3、Elasticsearch功能使用

第4章 功能使用 4.1 Java API 操作 随着 Elasticsearch 8.x 新版本的到来&#xff0c;Type 的概念被废除&#xff0c;为了适应这种数据结构的改 变&#xff0c;Elasticsearch 官方从 7.15 版本开始建议使用新的 Elasticsearch Java Client。 4.1.1 增加依赖关系 <propertie…

工作【当van-tab不满足固定在顶部】

背景 需要H5实现一下滑动列表&#xff0c;顶部tab栏可以切换&#xff0c;当向下滑动列表的时候tab栏固定到顶部。果断的看了一下官方文档&#xff1a; 就是这个&#xff0c;我一看还有扩展属性&#xff0c;非常友好。向下滑动查看文档 使用sticky实现的。众所周知&#xff0…

Python 计算三角形面积

"""计算三角形面积介绍&#xff1a;已知三角形边长分别为x、y、z&#xff0c;可以计算三角形半周长q&#xff0c;然后根据海伦公式计算三角形面积S三角形半周长&#xff1a;q (x y z) / 2三角形面积&#xff1a;S (q * (q-x) * (q-y) * (q-z)) ** 0.5知识点…

独辟蹊径”之动态切换进程代理IP

前言 项目中遇到这样一个需求&#xff0c;需要动态切换指定进程Sockets5代理IP&#xff0c;目前了解到可通过编写驱动拦截或者劫持LSP实现&#xff0c;LSP劫持不太稳定&#xff0c;驱动无疑是相对较好的解决方案&#xff0c;奈何水平不足便有了这"蹊径"。 初步尝试…

Mybatis SQL构建器

上一篇我们介绍了在Mybatis映射器中使用SelectProvider、InsertProvider、UpdateProvider、DeleteProvider进行对数据的增删改查操作&#xff1b;本篇我们介绍如何使用SQL构建器在Provider中优雅的构建SQL语句。 如果您对在Mybatis映射器中使用SelectProvider、InsertProvider…

反编译之崩溃定位

反编译之崩溃定位 1.背景问题定位1.首先我们需要找崩溃所在的类和方法2.寻找崩溃的代码行数2.1借用反编译工具jadx查看反编译后的内容 1.背景 线上出了个崩溃(量挺大&#x1f62d;)&#xff0c;但是apk是被混淆过的&#xff0c;一时摸不着头脑。崩溃信息如下&#xff1a; 主要…

yum 快速安装zookeeper、Kafka集群部署 es安装 logstash安装 kibina 分词器 redis

Zookeeper安装 Kafka是基于Zookeeper来实现分布式协调的&#xff0c;所以在搭建Kafka节点之前需要先搭建好Zookeeper节点。而Zookeeper和Kafka都依赖于JDK&#xff0c;我这里先安装好了JDK&#xff1a; 安装jdk yum install java-1.8.0-openjdk* -y 1 [root192.168.99.4 ~]#…