Qt 的 QThread:多线程编程的基础
Qt 的 QThread:多线程编程的基础
在现代应用程序中,尤其是需要处理大量数据、进行长时间计算或者进行 I/O 操作时,多线程编程变得至关重要。Qt 提供了一个功能强大且易于使用的线程类 QThread,可以帮助开发者在 Qt 应用程序中实现并发和并行操作。本文将详细介绍 QThread 的核心功能与常见使用方法,帮助你深入了解 Qt 的多线程机制,并更高效地使用它
1. QThread 的基本概念
QThread 是 Qt 框架中实现多线程的基础类,它允许开发者创建新的线程,并在其中执行任务。线程是一种轻量级的进程,它能并行执行任务,从而提高应用程序的响应速度和性能。每个 QThread 对象代表一个线程,线程之间的独立执行有助于分担主线程的压力,避免主界面的阻塞。
Qt 中的多线程模型基于事件驱动机制,因此线程的管理通常通过事件循环来进行,QThread 作为线程的容器,内置了事件循环机制。
2. 如何创建线程
在使用 QThread 时,开发者通常有两种方式来创建线程:
1.1 继承 QThread 类
最常见的方式是继承 QThread 类并重写其 run() 方法。run() 方法会在新线程中执行,因此你可以将具体的工作逻辑放在该方法中。
class MyThread : public QThread
{
public:void run() override{// 在新线程中执行的任务qDebug() << "Thread started!";}
};int main()
{MyThread *thread = new MyThread();thread->start(); // 启动线程thread->wait(); // 等待线程结束return 0;
}
在这个例子中,我们创建了一个名为 MyThread 的新类,它继承自 QThread 并重写了 run() 方法。调用 start() 函数后,run() 方法会在新线程中自动执行。
1.2 使用 QObject 与 moveToThread() 方法
另一种方法是通过 QObject 创建任务对象,并将该对象移到子线程中执行。这种方式适用于不想继承 QThread 类的情况,它通过 moveToThread() 方法将任务对象移到指定的线程中执行。
class Worker : public QObject
{Q_OBJECT
public slots:void doWork(){// 执行任务qDebug() << "Working in thread!";}
};int main()
{Worker *worker = new Worker();QThread *workerThread = new QThread();worker->moveToThread(workerThread);QObject::connect(workerThread, &QThread::started, worker, &Worker::doWork);QObject::connect(worker, &Worker::finished, workerThread, &QThread::quit);workerThread->start(); // 启动子线程workerThread->wait(); // 等待线程结束return 0;
}
这里,我们创建了一个 Worker 对象并将其移到 workerThread 中,接着在 workerThread 启动时调用 doWork() 方法,完成工作后通过信号与槽机制将工作结果传递回主线程。
3. QThread 的常用 API
3.1 启动与停止线程
start():启动线程,调用此方法会触发run()方法。quit():请求线程退出。线程会结束事件循环并退出。wait():等待线程执行完毕,通常在主线程中调用。
QThread *thread = new QThread();
thread->start(); // 启动线程
thread->wait(); // 等待线程结束
3.2 线程的状态
isRunning():检查线程是否正在运行。isFinished():检查线程是否已完成任务并退出。
if (thread->isRunning()) {qDebug() << "Thread is running.";
}if (thread->isFinished()) {qDebug() << "Thread is finished.";
}
3.3 设置线程优先级
setPriority():设置线程的优先级,Qt 提供了多个优先级选项,从低到高分别为:LowPriority、NormalPriority、HighPriority和HighestPriority。priority():获取线程的当前优先级。
thread->setPriority(QThread::HighPriority); // 设置线程为高优先级
3.4 线程事件循环
exec():启动线程的事件循环。如果需要线程中的事件循环处理,可以调用exec()。
thread->exec(); // 启动事件循环
3.5 线程间通信
在 Qt 中,线程间的通信通过信号与槽机制来实现。通过信号,子线程可以将数据或事件传递给主线程,或者主线程可以通知子线程执行某些操作。
QObject::connect(thread, &QThread::finished, thread, &QObject::deleteLater);
4. 线程管理与内存清理
在使用 QThread 时,正确地管理线程的生命周期至关重要。如果线程在完成任务后没有正确释放,可能会导致内存泄漏。
4.1 使用 deleteLater() 安全删除线程
deleteLater() 是 Qt 提供的一个方法,它会在事件循环中安全地删除对象。适用于避免在子线程中直接删除对象,从而避免线程安全问题。
QObject::connect(thread, &QThread::finished, thread, &QObject::deleteLater);
4.2 使用智能指针自动管理内存
如果你使用 C++11 或更高版本,可以通过智能指针(如 std::unique_ptr)来自动管理 QThread 对象的生命周期。
std::unique_ptr<QThread> thread = std::make_unique<QThread>();
QObject::connect(thread.get(), &QThread::finished, thread.get(), &QObject::deleteLater);
thread->start();
智能指针会在作用域结束时自动销毁对象,无需手动调用 delete。
5. 常见问题与调试技巧
5.1 线程阻塞问题
当线程执行任务时,可能会出现阻塞,尤其是在进行 I/O 操作或等待外部资源时。为避免这种情况,可以使用定时器或异步操作来避免线程长时间阻塞。
5.2 UI 线程安全问题
Qt 中的 UI 控件只能在主线程中更新。子线程不应直接修改 UI,而应该通过信号与槽机制将数据传递给主线程,由主线程更新 UI。
相关文章:
Qt 的 QThread:多线程编程的基础
Qt 的 QThread:多线程编程的基础 在现代应用程序中,尤其是需要处理大量数据、进行长时间计算或者进行 I/O 操作时,多线程编程变得至关重要。Qt 提供了一个功能强大且易于使用的线程类 QThread,可以帮助开发者在 Qt 应用程序中实现…...
周末总结(2024/11/16)
工作 人际关系核心实践: 要学会随时回应别人的善意,执行时间控制在5分钟以内 坚持每天早会打招呼 遇到接不住的话题时拉低自己,抬高别人(无阴阳气息) 朋友圈点赞控制在5min以内,职场社交不要放在5min以外 职场的人际关系在面对利…...
Chrome和Chromium的区别?浏览器引擎都用的哪些?浏览器引擎的作用?
Chrome和Chromium的区别? Chrome是Google专属的产品,它是基于后者Chromium开源引擎开发。第三方浏览器公司为了加快开发流程,会直接选择开源的浏览器引擎,例如Chromium. Google将Chromium开源,本意为了打破浏览器被其他公司控制的…...
流程图图解@RequestBody @RequestPart @RequestParam @ModelAttribute
RequestBody 只能用一次,因为只有一个请求体 #mermaid-svg-8WZfkzl0GPvOiNj3 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-8WZfkzl0GPvOiNj3 .error-icon{fill:#552222;}#mermaid-svg-8WZfkzl0GPvOiNj…...
AutoUpdater.NET 实现 dotNET应用自动更新
AutoUpdater.NET 是一款用于WPF、Winform软件版本更新的框架,类似框架还有Squirrel、WinSparkle、NetSparkle、Google Omaha。 一、安装AutoUpdater.NET 首先,您需要在项目中安装AutoUpdater.NET库。您可以通过NuGet包管理器来安装它。在Visual Studio中…...
108. UE5 GAS RPG 实现地图名称更新和加载关卡
在这一篇里,我们将实现对存档的删除功能,在删除时会有弹框确认。接着实现获取玩家的等级和地图名称和存档位置,我们可以通过存档进入游戏,玩家在游戏中可以在存档点存储存档。 实现删除存档 删除存档需要一个弹框确认࿰…...
对称加密与非对称加密:密码学的基石及 RSA 算法详解
对称加密与非对称加密:密码学的基石及 RSA 算法详解 在当今数字化的时代,信息安全至关重要。对称加密和非对称加密作为密码学中的两种基本加密技术,为我们的数据安全提供了强大的保障。本文将深入探讨对称加密和非对称加密的特点、应用场景&…...
排列问题方法总结(递归+迭代)
递归 一、逐步生成结果法(无序) #include<iostream> #include<vector> #include<string> #include<algorithm>using namespace std;vector<string> GetChild(int n,int curIndex){vector<string> now;vector&…...
C#从入门到放弃
C#和.NET的区别 C# C#是一个编程语言 .NET .NET是一个在window下创建程序的框架 .NET框架不仅局限于C#,它还可以支持很多语言 .NET包括了2个组件,一个叫CLR(通用语言运行时),另一个是用来构建程序的类库 CLR 用C写一个程序,在一台8688的机器…...
视频质量评价学习笔记
目录 MD VQA:大淘宝团队: ReIQA KVQ 视频质量评价学习笔记 MD VQA:大淘宝团队: https://github.com/kunyou99/MD-VQA_cvpr2023?tabreadme-ov-file ReIQA GitHub - avinabsaha/ReIQA: Official implementation for CVPR2023 Paper "Re-IQA : U…...
OpenCV、YOLO、VOC、COCO之间的关系和区别
OpenCV、YOLO、COCO 和 VOC 是计算机视觉和深度学习领域常见的几个名词,它们分别代表不同的工具、算法和数据集,之间有一些联系和区别。下面分别说明它们的定义、用途以及相互关系。 1. OpenCV(Open Source Computer Vision Library…...
Pandas进行周期与时间戳转换
时间序列数据在数据分析和金融领域非常常见,处理这些数据时,通常会面临周期(Period)与时间戳(Timestamp)之间的转换需求。理解和掌握这种转换,对于时间序列数据的清洗、预处理以及进一步分析至关重要。Python 中的 pandas 库提供了一系列便捷的函数来帮助处理这些时间序…...
【GPTs】Get Simpsonized:一键变身趣味辛普森角色
博客主页: [小ᶻZ࿆] 本文专栏: AIGC | GPTs应用实例 文章目录 💯GPTs指令💯前言💯Get Simpsonized主要功能适用场景优点缺点使用方式 💯小结 💯GPTs指令 中文翻译: 指令保护和安全规则&…...
概率论公式整理
1 概率 古典概型和几何概型 古典概型(有限等可能)几何概型(无限等可能) 条件概率 P ( A ∣ B ) P ( A B ) P ( B ) P(A|B) \frac{P(AB)}{P(B)} P(A∣B)P(B)P(AB) 全概率公式 P ( B ) ∑ i 1 n P ( A i ) P ( B ∣ A i ) P…...
【C++】—— stack和queue的模拟实现
前言 stack 和 queue使用起来都非常简单,现在来模拟实现一下,理解其底层的原理。 在实现之前,应该知道,stack 和 queue 都是容器适配器,通过看官网文件也可以看出来;其默认的容器都是dequeÿ…...
管家婆工贸ERP BR039.采购订单关联MRP明细表
最低适用版本: 工贸系列 23.8 插件简要功能说明: 采购订单明细表,支持显示采购订单明细上游请购单明细关联的MRP中对应销售订单明细产成品相关信息更多细节描述见下方详细文档 插件操作视频: 进销存类定制插件--采购订单关联M…...
SwanLab安装教程
SwanLab是一款开源、轻量级的AI实验跟踪工具,提供了一个跟踪、比较、和协作实验的平台,旨在加速AI研发团队100倍的研发效率。 其提供了友好的API和漂亮的界面,结合了超参数跟踪、指标记录、在线协作、实验链接分享、实时消息通知等功能&…...
MySQL EXPLAIN,数据库调优的秘密通道
EXPLAIN 是 MySQL 中一个非常有用的工具,它用于分析 SQL 查询的执行计划。通过 EXPLAIN,你可以获取 MySQL 是如何准备执行你的 SQL 语句的,包括使用的索引、连接类型、扫描的行数等信息。这些信息对于优化查询性能、识别性能瓶颈至关重要。 使…...
利用redis的key失效监听器KeyExpirationEventMessageListener作任务定时提醒功能
某需求: 要求在任务截止日期的前3天时,系统自动给用户发一条消息提醒。 用定时任务的话感觉很不舒服。间隔时间不好弄。不能精准卡到那个点。 由于系统简单,没有使用消息列队,也不能使用延时队列来做。 用Timer的话开销还挺大的&a…...
如何基于Tesseract实现图片的文本识别
在前一篇文章基础上,如何将报告图片中的文本解析出来,最近研究了基于Tesseract的OCR方案,Tesseract OCR是一个开源的OCR引擎,主要结合开源的tesseract和pytesseract,实现了jpg/png等格式图片文本识别,供大家…...
双向无线功率传输系统模型附Simulink仿真
✅作者简介:热爱科研的Matlab仿真开发者,擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室🍊个人信条:格物致知,完整Matlab代码及仿真咨询…...
从‘虚拟’到‘物理’:程序员视角下的内存块、页框与页到底是怎么协作的?
从‘虚拟’到‘物理’:程序员视角下的内存块、页框与页到底是怎么协作的? 当你调试程序时遇到"Segmentation fault"或"Page fault"错误,是否好奇这些术语背后究竟发生了什么?作为开发者,我们每天都…...
ArduinoFritzApi:嵌入式设备对接FRITZ!Box的TR-064协议实践
1. ArduinoFritzApi 库深度解析:面向嵌入式系统的 FRITZ!Box 自动化控制实践指南1.1 库定位与工程价值ArduinoFritzApi 是一个专为嵌入式平台设计的轻量级 C 库,其核心目标是实现对 AVM 公司全系智能家庭设备(FRITZ!Box 路由器、FRITZ!DECT 插…...
Polars 2.0大规模清洗性能翻倍的7个底层优化技巧:基于真实金融风控流水线压测数据
第一章:Polars 2.0大规模数据清洗性能跃迁的工程意义Polars 2.0 的发布标志着 Rust 原生 DataFrame 库在工程落地层面实现关键突破——其基于 Arrow 2.0 和全新查询优化器(QOv2)重构的执行引擎,将典型 ETL 清洗任务的吞吐量提升达…...
十字头零件的机械加工工艺规程及工装夹具设计 (论文+CAD图纸+任务书+过程卡+工序卡+外文翻译+参考文献……)
十字头零件作为机械传动系统中的关键构件,其加工精度直接影响设备运行的稳定性与寿命。制定科学合理的机械加工工艺规程及配套工装夹具设计方案,是确保零件质量、提升加工效率的核心环节。工艺规程需系统规划从毛坯准备到成品检验的全流程,涵…...
解锁B站视频下载:5个高效技巧让你轻松获取心仪内容
解锁B站视频下载:5个高效技巧让你轻松获取心仪内容 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader 😳 项目地址: https://gitcode.com/gh_mirrors/bi/B…...
视频技术三要素:码率、帧率与分辨率的实战解析
1. 视频三要素的基础认知 第一次接触视频制作时,我被各种专业术语搞得晕头转向。直到有前辈告诉我:"其实只要搞懂码率、帧率和分辨率这三个参数,就能解决80%的视频质量问题。"这句话让我茅塞顿开,今天我就把这些年积累的…...
OpenClaw 的模型架构中,是否使用了混合专家(MoE)的负载均衡策略?
关于OpenClaw模型架构中是否采用了混合专家(MoE)的负载均衡策略,这个问题其实触及了当前大模型设计里一个相当有意思的细节。直接说结论的话,从目前公开的论文和技术报告来看,OpenClaw并没有明确声明在其MoE层中使用了…...
百考通:AI全流程智能化赋能期刊论文写作,让学术创作更高效
在学术研究领域,期刊论文的撰写是成果输出的关键环节,却也让众多科研工作者与学生倍感压力:选题迷茫、逻辑梳理困难、格式规范复杂、内容提炼耗时,严重拖慢了学术成果的发表节奏。百考通(https://www.baikaotongai.com…...
如何创建自定义编程连字符号:Hasklig字体开发终极指南
如何创建自定义编程连字符号:Hasklig字体开发终极指南 【免费下载链接】Hasklig Hasklig - a code font with monospaced ligatures 项目地址: https://gitcode.com/gh_mirrors/ha/Hasklig Hasklig是一款专为程序员设计的等宽字体,它通过创新的连…...
