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

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 使用 QObjectmoveToThread() 方法

另一种方法是通过 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 提供了多个优先级选项,从低到高分别为:LowPriorityNormalPriorityHighPriorityHighestPriority
  • 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&#xff1a;多线程编程的基础 在现代应用程序中&#xff0c;尤其是需要处理大量数据、进行长时间计算或者进行 I/O 操作时&#xff0c;多线程编程变得至关重要。Qt 提供了一个功能强大且易于使用的线程类 QThread&#xff0c;可以帮助开发者在 Qt 应用程序中实现…...

周末总结(2024/11/16)

工作 人际关系核心实践&#xff1a; 要学会随时回应别人的善意&#xff0c;执行时间控制在5分钟以内 坚持每天早会打招呼 遇到接不住的话题时拉低自己&#xff0c;抬高别人(无阴阳气息) 朋友圈点赞控制在5min以内&#xff0c;职场社交不要放在5min以外 职场的人际关系在面对利…...

Chrome和Chromium的区别?浏览器引擎都用的哪些?浏览器引擎的作用?

Chrome和Chromium的区别? Chrome是Google专属的产品&#xff0c;它是基于后者Chromium开源引擎开发。第三方浏览器公司为了加快开发流程&#xff0c;会直接选择开源的浏览器引擎&#xff0c;例如Chromium. Google将Chromium开源&#xff0c;本意为了打破浏览器被其他公司控制的…...

流程图图解@RequestBody @RequestPart @RequestParam @ModelAttribute

RequestBody 只能用一次&#xff0c;因为只有一个请求体 #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软件版本更新的框架&#xff0c;类似框架还有Squirrel、WinSparkle、NetSparkle、Google Omaha。 一、安装AutoUpdater.NET 首先&#xff0c;您需要在项目中安装AutoUpdater.NET库。您可以通过NuGet包管理器来安装它。在Visual Studio中…...

108. UE5 GAS RPG 实现地图名称更新和加载关卡

在这一篇里&#xff0c;我们将实现对存档的删除功能&#xff0c;在删除时会有弹框确认。接着实现获取玩家的等级和地图名称和存档位置&#xff0c;我们可以通过存档进入游戏&#xff0c;玩家在游戏中可以在存档点存储存档。 实现删除存档 删除存档需要一个弹框确认&#xff0…...

对称加密与非对称加密:密码学的基石及 RSA 算法详解

对称加密与非对称加密&#xff1a;密码学的基石及 RSA 算法详解 在当今数字化的时代&#xff0c;信息安全至关重要。对称加密和非对称加密作为密码学中的两种基本加密技术&#xff0c;为我们的数据安全提供了强大的保障。本文将深入探讨对称加密和非对称加密的特点、应用场景&…...

排列问题方法总结(递归+迭代)

递归 一、逐步生成结果法&#xff08;无序&#xff09; #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个组件&#xff0c;一个叫CLR(通用语言运行时)&#xff0c;另一个是用来构建程序的类库 CLR 用C写一个程序&#xff0c;在一台8688的机器…...

视频质量评价学习笔记

目录 MD VQA:大淘宝团队&#xff1a; ReIQA KVQ 视频质量评价学习笔记 MD VQA:大淘宝团队&#xff1a; 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 是计算机视觉和深度学习领域常见的几个名词&#xff0c;它们分别代表不同的工具、算法和数据集&#xff0c;之间有一些联系和区别。下面分别说明它们的定义、用途以及相互关系。 1. OpenCV&#xff08;Open Source Computer Vision Library&#xf…...

Pandas进行周期与时间戳转换

时间序列数据在数据分析和金融领域非常常见,处理这些数据时,通常会面临周期(Period)与时间戳(Timestamp)之间的转换需求。理解和掌握这种转换,对于时间序列数据的清洗、预处理以及进一步分析至关重要。Python 中的 pandas 库提供了一系列便捷的函数来帮助处理这些时间序…...

【GPTs】Get Simpsonized:一键变身趣味辛普森角色

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | GPTs应用实例 文章目录 &#x1f4af;GPTs指令&#x1f4af;前言&#x1f4af;Get Simpsonized主要功能适用场景优点缺点使用方式 &#x1f4af;小结 &#x1f4af;GPTs指令 中文翻译&#xff1a; 指令保护和安全规则&…...

概率论公式整理

1 概率 古典概型和几何概型 古典概型&#xff08;有限等可能&#xff09;几何概型&#xff08;无限等可能&#xff09; 条件概率 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使用起来都非常简单&#xff0c;现在来模拟实现一下&#xff0c;理解其底层的原理。 ​ 在实现之前&#xff0c;应该知道&#xff0c;stack 和 queue 都是容器适配器&#xff0c;通过看官网文件也可以看出来&#xff1b;其默认的容器都是deque&#xff…...

管家婆工贸ERP BR039.采购订单关联MRP明细表

最低适用版本&#xff1a; 工贸系列 23.8 插件简要功能说明&#xff1a; 采购订单明细表&#xff0c;支持显示采购订单明细上游请购单明细关联的MRP中对应销售订单明细产成品相关信息更多细节描述见下方详细文档 插件操作视频&#xff1a; 进销存类定制插件--采购订单关联M…...

SwanLab安装教程

SwanLab是一款开源、轻量级的AI实验跟踪工具&#xff0c;提供了一个跟踪、比较、和协作实验的平台&#xff0c;旨在加速AI研发团队100倍的研发效率。 其提供了友好的API和漂亮的界面&#xff0c;结合了超参数跟踪、指标记录、在线协作、实验链接分享、实时消息通知等功能&…...

MySQL EXPLAIN,数据库调优的秘密通道

EXPLAIN 是 MySQL 中一个非常有用的工具&#xff0c;它用于分析 SQL 查询的执行计划。通过 EXPLAIN&#xff0c;你可以获取 MySQL 是如何准备执行你的 SQL 语句的&#xff0c;包括使用的索引、连接类型、扫描的行数等信息。这些信息对于优化查询性能、识别性能瓶颈至关重要。 使…...

利用redis的key失效监听器KeyExpirationEventMessageListener作任务定时提醒功能

某需求&#xff1a; 要求在任务截止日期的前3天时&#xff0c;系统自动给用户发一条消息提醒。 用定时任务的话感觉很不舒服。间隔时间不好弄。不能精准卡到那个点。 由于系统简单&#xff0c;没有使用消息列队&#xff0c;也不能使用延时队列来做。 用Timer的话开销还挺大的&a…...

如何基于Tesseract实现图片的文本识别

在前一篇文章基础上&#xff0c;如何将报告图片中的文本解析出来&#xff0c;最近研究了基于Tesseract的OCR方案&#xff0c;Tesseract OCR是一个开源的OCR引擎&#xff0c;主要结合开源的tesseract和pytesseract&#xff0c;实现了jpg/png等格式图片文本识别&#xff0c;供大家…...

双向无线功率传输系统模型附Simulink仿真

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f34a;个人信条&#xff1a;格物致知,完整Matlab代码及仿真咨询…...

从‘虚拟’到‘物理’:程序员视角下的内存块、页框与页到底是怎么协作的?

从‘虚拟’到‘物理’&#xff1a;程序员视角下的内存块、页框与页到底是怎么协作的&#xff1f; 当你调试程序时遇到"Segmentation fault"或"Page fault"错误&#xff0c;是否好奇这些术语背后究竟发生了什么&#xff1f;作为开发者&#xff0c;我们每天都…...

ArduinoFritzApi:嵌入式设备对接FRITZ!Box的TR-064协议实践

1. ArduinoFritzApi 库深度解析&#xff1a;面向嵌入式系统的 FRITZ!Box 自动化控制实践指南1.1 库定位与工程价值ArduinoFritzApi 是一个专为嵌入式平台设计的轻量级 C 库&#xff0c;其核心目标是实现对 AVM 公司全系智能家庭设备&#xff08;FRITZ!Box 路由器、FRITZ!DECT 插…...

Polars 2.0大规模清洗性能翻倍的7个底层优化技巧:基于真实金融风控流水线压测数据

第一章&#xff1a;Polars 2.0大规模数据清洗性能跃迁的工程意义Polars 2.0 的发布标志着 Rust 原生 DataFrame 库在工程落地层面实现关键突破——其基于 Arrow 2.0 和全新查询优化器&#xff08;QOv2&#xff09;重构的执行引擎&#xff0c;将典型 ETL 清洗任务的吞吐量提升达…...

十字头零件的机械加工工艺规程及工装夹具设计 (论文+CAD图纸+任务书+过程卡+工序卡+外文翻译+参考文献……)

十字头零件作为机械传动系统中的关键构件&#xff0c;其加工精度直接影响设备运行的稳定性与寿命。制定科学合理的机械加工工艺规程及配套工装夹具设计方案&#xff0c;是确保零件质量、提升加工效率的核心环节。工艺规程需系统规划从毛坯准备到成品检验的全流程&#xff0c;涵…...

解锁B站视频下载:5个高效技巧让你轻松获取心仪内容

解锁B站视频下载&#xff1a;5个高效技巧让你轻松获取心仪内容 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader &#x1f633; 项目地址: https://gitcode.com/gh_mirrors/bi/B…...

视频技术三要素:码率、帧率与分辨率的实战解析

1. 视频三要素的基础认知 第一次接触视频制作时&#xff0c;我被各种专业术语搞得晕头转向。直到有前辈告诉我&#xff1a;"其实只要搞懂码率、帧率和分辨率这三个参数&#xff0c;就能解决80%的视频质量问题。"这句话让我茅塞顿开&#xff0c;今天我就把这些年积累的…...

OpenClaw 的模型架构中,是否使用了混合专家(MoE)的负载均衡策略?

关于OpenClaw模型架构中是否采用了混合专家&#xff08;MoE&#xff09;的负载均衡策略&#xff0c;这个问题其实触及了当前大模型设计里一个相当有意思的细节。直接说结论的话&#xff0c;从目前公开的论文和技术报告来看&#xff0c;OpenClaw并没有明确声明在其MoE层中使用了…...

百考通:AI全流程智能化赋能期刊论文写作,让学术创作更高效

在学术研究领域&#xff0c;期刊论文的撰写是成果输出的关键环节&#xff0c;却也让众多科研工作者与学生倍感压力&#xff1a;选题迷茫、逻辑梳理困难、格式规范复杂、内容提炼耗时&#xff0c;严重拖慢了学术成果的发表节奏。百考通&#xff08;https://www.baikaotongai.com…...

如何创建自定义编程连字符号:Hasklig字体开发终极指南

如何创建自定义编程连字符号&#xff1a;Hasklig字体开发终极指南 【免费下载链接】Hasklig Hasklig - a code font with monospaced ligatures 项目地址: https://gitcode.com/gh_mirrors/ha/Hasklig Hasklig是一款专为程序员设计的等宽字体&#xff0c;它通过创新的连…...