当前位置: 首页 > news >正文

QtC++使用QRunnable+QThreadPool管理多线程

本文的示例项目工程在文章最后有分享链接,可以下载运行试试。下载后替换成自己的Qt版本即可(项目 -> 属性 -> 配置属性 -> Qt Project Settings -> Qt Installation)

应用场景介绍

现有一个应用场景,需要进行上千个循环里面,调用相同的功能类去计算,只使用一个线程去计算,效率太低,结合网络上的帖子和自身实践。我的实现场景如下:

  1. 界面类Dialog。给用户提供交互操作
  2. 计算类Logic。执行用户点击后的计算逻辑
  3. 任务类QRunnable。在若干循环里面用于完成指定任务

运行过程

在Qt界面中,用户点击某个控件后,创建一个线程去执行计算操作,避免界面阻塞,陷入卡死。
(这里有个不继承 qthread 使用多线程的方法,提供另一种实现方法思路)

QThread*mThread;//!< 计算类执行的线程Calculate*mCalculate;//!< 计算类,放在mThread线程里面执行,避免界面卡死/************************************************************************//* 上面为成员变量 *//************************************************************************/mThread=newQThread();mCalculate=newCalculate();mCalculate->moveToThread(mThread);// 改变mCalculate的线程依附关系,将计算类放在线程中执行//! 释放堆空间资源,避免内存泄露connect(mThread,&QThread::finished,mThread,&QObject::deleteLater);connect(mThread,&QThread::finished,mCalculate,&QObject::deleteLater);//! 注意:在使用跨线程通信时,参数需要为元数据类型(具体我也解释不清楚,理解是有关 meta 什么的)qRegisterMetaType<CalculateInputStruct>("CalculateInputStruct");// 将结构体 CalculateInputStruct 注册为元数据类型//! 连接其他信号槽,用于触发线程执行槽函数里的任务connect(this,&MultiThreadDemo::StartCalculate,mCalculate,&Calculate::startCalculateSlot,Qt::QueuedConnection);// 默认使用Qt::QueuedConnection,保证槽函数的执行顺序connect(mCalculate,&Calculate::CalculateFinished,this,&MultiThreadDemo::calculate_finished_slot,Qt::QueuedConnection);// 计算完成显示信息connect(mCalculate,&Calculate::UpdateProssorbar,this,&MultiThreadDemo::update_prossorbar_slot,Qt::QueuedConnection);// 每计算一次完一次任务,更新界面进度条mThread->start();// 启动线程,线程默认开启事件循环,并且线程正处于事件循环状态

类似Run函数实现

计算类使用 qthreadpool 线程池实现,这里的任务是独立的,每个计算任务仅使用传递的参数,没有涉及资源共享

voidCalculate::startCalculateSlot(constCalculateInputStruct aInput){autotest_thread_id=QThread::currentThreadId();// 查看当前线程的id和界面类、任务类的id是否相同QThreadPool thread_pool;thread_pool.setMaxThreadCount(aInput.threadMaxCount);// 设置线程池的最大线程数为1for(inti=0;i<aInput.calculateCount;i++){CalculateRunnable*runnable=newCalculateRunnable;runnable->setAutoDelete(true);// 设置任务结束后自动删除thread_pool.start(runnable);//! 设置响应方式为消息队列时,会在emit CalculateFinished(); 后再响应,故这里使用直接响应connect(runnable,&CalculateRunnable::RunnableFinished,this,[&](){emitUpdateProssorbar();},Qt::DirectConnection);}thread_pool.waitForDone();// 等待所有任务完成emitCalculateFinished();}}

结果对比

一个任务类在run函数中的计算为0.5s。可以看出,理论上线程池中还是有效的。

参考

在寻找答案的过程中,看了很多帖子,分享几遍个人觉得质量不错的文章

  1. Qt多线程通信
  2. Qt线程之QRunnable的使用详解
  3. QT 多线程的实现方法以及GUI线程与其他线程间的通信
  4. 【QT】子类化QObject+moveToThread实现多线程
  5. Qt使用多线程的一些心得——1.继承QThread的多线程使用方法

工程示例

  1. 开发环境:Qt5.15.2 + vs2022
  2. csdn链接:https://download.csdn.net/download/weixin_51238542/90291812
  3. 百度网盘链接:https://pan.baidu.com/s/1JkKm6QF1TrFbQbgyaPqZSw?pwd=tvhn
  4. github链接:https://github.com/tianxingithub/MultiThreadDemo
http://www.jsqmd.com/news/713345/

相关文章:

  • 2026最新面霜/面膜公司/供应商/厂家推荐!国内优质榜单发布,广东广州等地实力厂商精选 - 十大品牌榜
  • 湖北音响改装哪家强?2026年04月精选门店推荐,宝马原厂音响升级/宝马音响改装,音响改装旗舰店哪家可靠 - 品牌推荐师
  • 2026 综合型私域电商平台排名|五大优质平台深度推荐 - 速递信息
  • 避开这3个坑,你的PSIM Boost电路仿真结果才准(以12V转36V为例)
  • 告别信号槽连接失败:深入Qt MOC机制,解决Q_OBJECT宏的五大常见坑
  • 2026年贵阳南明区炭火烤肉与烤鱼宵夜地标选购指南 - 年度推荐企业名录
  • 成都靠谱装修公司怎么选?|2026高口碑装修公司合集,半包/设计/整装/旧房改造无坑推荐 - 成都人评鉴
  • Balena Etcher深度解析:三步解决90%的系统镜像烧录难题
  • SOCD Cleaner技术深度解析:重新定义游戏输入处理
  • 开源项目合规警示:从PyWxDump看技术边界与法律红线
  • 【译】在 Visual Studio 中完全掌控您的悬浮窗口
  • FakeLocation技术方案:基于Xposed框架实现80%资源优化的应用级位置模拟引擎
  • 二叉搜索树的后序遍历序列-C++
  • SublimeREPL架构解析:深入理解REPL插件的设计原理
  • 2026年贵阳炭火烤肉与竹签烤肉正宗铁签烤肉店怎么选 - 年度推荐企业名录
  • 房产中介佣金计算太复杂?一张决策表带你理清所有测试场景(附完整用例模板)
  • 2025届学术党必备的AI科研网站横评
  • 把数组排成最小的数-C++
  • Windows蓝屏0xE6?别慌,手把手教你用WinDbg分析DRIVER_VERIFIER_DMA_VIOLATION
  • 3个步骤解锁Switch终极潜能:大气层系统完整安装与使用指南
  • MouseClick鼠标连点器:智能化跨平台自动化解决方案深度解析
  • 从零到上手:用SmartBI V10.x实战演练数据可视化全流程(附自助仪表盘与大屏制作避坑指南)
  • 告别网盘限速:LinkSwift直链下载工具终极指南
  • 终极FF14过场动画跳过插件:3分钟快速上手完整指南
  • 摄像机标定
  • 快速体验胶片质感AI绘画:FLUX.1-Krea真实感模型部署与试用
  • 别再被PyTorch的checkpoint坑了!深入state_dict,彻底搞懂参数组匹配问题
  • 3行命令搞定抖音批量下载:douyin-downloader无水印视频下载终极指南
  • 如何实现跨平台设备无缝发现?LocalSend零配置识别技术全解析
  • 2025最权威的六大AI学术助手推荐