Qt 多线程编程: moveToThread 模式讲解

目录

Qt 多线程编程: moveToThread 模式

核心理念

旧做法:继承 QThread

推荐:moveToThread

实现步骤图解

1. 定义 Worker

2. 实例化 QThread

3. 移动对象

4. 连接与启动

最佳实践与常见陷阱


Qt 多线程编程: moveToThread 模式

这是 Qt 官方推荐的 "Worker-Object" 多线程实现方式。告别错误的QThread继承法,掌握真正的事件驱动多线程模型。

核心理念

为什么选择 Worker-Object 模式?

很多人误以为QThread本身就是线程。其实,QThread只是线程的管理者。

旧做法:继承 QThread

直接重写run()函数。这种做法使得只有 run 函数内部的代码在子线程运行,而类中的槽函数(Slot)依然在主线程运行,极易导致线程安全问题。

推荐:moveToThread

创建一个继承自QObject的 Worker 类,实例化后使用obj->moveToThread(thread)移动它。这样该对象的所有槽函数都会自动在子线程中执行。

实现步骤图解

1. 定义 Worker

创建一个继承 QObject 的类,把耗时任务写在槽函数里。

2. 实例化 QThread

创建一个普通的 QThread 对象,不需要继承它。

3. 移动对象

调用worker->moveToThread(thread)

4. 连接与启动

连接信号槽,然后调用thread->start()

最佳实践与常见陷阱

陷阱:在 Worker 的构造函数中创建对象

千万不要这样做。如果在 Worker 构造函数里new QTimer或其他 QObject,这些子对象会属于创建 Worker 的线程(通常是主线程)。当你调用moveToThread时,虽然 Worker 移动了,但它的子对象可能不会正确移动(如果它们已经设置了父子关系,会一起移动;但如果没有父子关系,就会留在主线程)。

最佳实践:在 Worker 的start()init()槽函数中分配资源,该槽函数在线程启动后通过信号触发执行。

内存管理:如何优雅退出?

线程结束后需要清理QThread对象和Worker对象。推荐的连接方式是:

  • connect(worker, &Worker::finished, thread, &QThread::quit); // 工人干完活,告诉线程退出循环
  • connect(worker, &Worker::finished, worker, &Worker::deleteLater); // 工人干完活,销毁自己
  • connect(thread, &QThread::finished, thread, &QThread::deleteLater); // 线程退出后,销毁线程对象

QtConcurrent vs QThreadexpand_more

并不是所有多线程都需要moveToThread

  • QtConcurrent::run:适合 "用完即走" 的一次性计算任务,不需要事件循环,不需要长期驻留。
  • moveToThread:适合需要长期运行、处理多个信号、需要事件循环(Event Loop)的服务型任务(如串口通信、TCP服务器、硬件轮询)。

注意点:

  • quit()只是请求线程事件循环退出;

  • wait()阻塞等到线程真的结束

  • 如果wait()返回了(没超时、没卡住),那说明线程已经结束了,QThread::finished一定已经在结束过程中发出过

  • 但这个if代码块“执行结束”并不等于一定会结束:如果线程里有阻塞/死循环,wait()可能一直卡住,代码块就不会结束,也谈不上发finished

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

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

相关文章

不是护眼灯不好,而是眼调节训练灯更懂孩子近视的防控需求

“又揉眼睛了?是不是看不清黑板了?”每天傍晚,不少家长看到孩子揉眼、眯眼的动作,都会心头一紧。为了守护孩子的“心灵窗户”,护眼灯成了书桌前的标配。可即便换了好几盏宣称“无频闪、低蓝光”的护眼灯,孩…

网站域名:关键的战略资产

网站域名:关键的战略资产 引言 在数字化时代,网站域名已经成为企业、个人乃至政府机构的战略资产。它不仅是网络身份的象征,更是连接用户和内容的重要桥梁。本文将深入探讨网站域名的概念、重要性、选择标准以及管理策略。 一、什么是网站域名? 网站域名是由一串由字母…

n8n第十节 把Markdown格式的会议纪要发到企微

朋友们,有没有感觉整理纪要格式很乱,发到企微群里还得截图,别人看着也费劲。今天教你——用n8n工作流,把AI生成的Markdown格式会议纪要,原汁原味直接发到企业微信!最大亮点:直接传Markdown格式&…

Pandas DataFrame:数据处理的强大工具

Pandas DataFrame:数据处理的强大工具 引言 在数据分析领域,Pandas DataFrame 是一个不可或缺的工具。它是 Python 中一个强大的数据分析库,能够帮助我们高效地处理和分析数据。本文将详细介绍 Pandas DataFrame 的概念、特点、使用方法以及在实际应用中的优势。 什么是 …

jQuery 捕获详解

jQuery 捕获详解 引言 在网页开发中,JavaScript 函数是动态改变页面内容的基础。jQuery 作为一种流行的 JavaScript 库,极大地简化了 DOM 操作。在 jQuery 中,捕获(Capture)是一种处理事件的技术,本文将深入探讨 jQuery 捕获的原理、方法和应用场景。 捕获原理 捕获是…

Foundation CSS 可见性

Foundation CSS 可见性 引言 在网页设计中,CSS(层叠样式表)是一种用于描述HTML或XML文档样式的样式表语言。CSS的可见性是网页设计中一个至关重要的概念,它决定了元素在页面上的显示方式。本文将深入探讨Foundation CSS框架中的可见性相关特性,帮助开发者更好地理解和应…

【图像加密】基于matlab超混沌序列和DNA序列图像加密【含Matlab源码 14689期】

💥💥💥💥💥💥💞💞💞💞💞💞💞💞欢迎来到海神之光博客之家💞💞💞&#x1f49…

SOAP 语法

SOAP 语法 概述 SOAP(Simple Object Access Protocol)是一种轻量级、简单的协议,用于在网络上交换结构化信息。它基于XML格式,支持多种传输协议,如HTTP、SMTP等。SOAP主要用于实现不同系统之间的互操作性,特别是在Web服务领域。 本文将详细介绍SOAP的语法,包括其基本…

QOwnNotes 开源 Markdown 笔记本 v25.12.5

软件介绍 QOwnNotes是开源的记事本,具有 Markdown支持 和针对GNU / Linux,Mac OS X和Windows的待办事项列表管理器,可与Nextcloud Notes 和ownCloud Notes一起使用。 您可以使用QOwnNotes写下您的想法,并 稍后在移动设备上进行编…

《Effective Java》第24条:静态成员类优于非静态成员类

说明: 关于本博客使用的书籍,源代码Gitee仓库 和 其他的相关问题,请查看本专栏置顶文章:《Effective Java》第0条:写在前面,用一年时间来深度解读《Effective Java》这本书 正文: 学习本条之前,首先来了解一下嵌套类 原文P88:嵌套类:是指定义在另一个类的内部的类…

LC项目实战一:PCB设计(三)

一、原理图导入变更设计-从原理图导入变更单击“应用修改”快速布局2D渲染效果图3D渲染效果图通过鼠标左键可以旋转3D效果图二、PCB图层和布线布线快捷键与原理图相同,使用ALT键加W键。布线时鼠标放在焊盘中间,有轻微吸附效果。点击鼠标左键确定导线起点…

Web Services 总结

Web Services 总结 引言 Web Services 是一种广泛应用于互联网上的服务架构,它允许不同平台、不同语言、不同操作系统的应用程序之间进行通信和交互。随着互联网技术的不断发展,Web Services 已经成为了企业级应用开发中不可或缺的一部分。本文将对 Web Services 进行全面总…

LC项目实战一:PCB DRC(四)

一、DRC设计-检查DRC没有消息就是最好的消息二、DRC错误演示三、DRC检查项目四、DRC设计规则

三种方式打 Java 可执行 JAR 包,你用对了吗?

三种方式打 Java 可执行 JAR 包,你用对了吗?写完代码只是开始,如何打包成一个“开箱即用”的 JAR 文件,才是交付的关键一步。很多 Java 开发者都遇到过这样的问题: 本地跑得好好的程序,一打包就报错 ClassN…

【题解】Luogu P10502 Matrix Power Series

题意分析 给定一个 \(n \times n\) 的矩阵 \(A\) 和正整数 \(k\),求 \(S=A^1+A^2+\cdots+A^k\)。 解题思路 求 \(A^n\) 要用到矩阵快速幂。但是 \(k \le 10^9\),求 \(k\) 个幂会超时,所以需要用到分治的策略。 我们…

【题解】Luogu P5175 数列

题目大意 给定一个递推式 \(a_n=x \times a_{n-1}+ y \times a_{n-2}(n≥3)\),求 \(\sum_{i=1}^na_i^2\)。 解题思路 递推通常是 \(O(n)\) 解法,但是本题 \(1 \le n \le 10^{18}\) 且 \(T=30000\)(注意是等于),所…

深入Ascend C:华为昇腾AI芯片的高性能编程语言详解

引言 随着人工智能技术的迅猛发展,专用AI加速芯片逐渐成为推动大模型训练与推理的核心硬件。在这一背景下,华为推出的昇腾(Ascend)系列AI处理器凭借其高能效比、大规模并行计算能力以及完整的软硬件生态体系,迅速在全…

SpringBoot 企业级接口加密【通用、可配置、解耦的组件】「开闭原则+模板方法+拦截器/中间件模式」

将加解密逻辑封装成通用、可配置、解耦的组件,核心是遵循「开闭原则模板方法拦截器/中间件模式」,让业务代码无需嵌入加密逻辑,仅通过注解/配置指定需要加密的接口/字段即可。以下是落地方案,以Java Spring Boot(主流企…

论文AI率90%→5%!DeepSeek四大降ai率指令+3款神器实测(保姆级教程)

从高校毕业论文到期刊审稿,2025年的AIGC检测已经成为了所有人的“噩梦”。很多同学拿着DeepSeek或GPT生成的论文去查,AI率直接飙红到90%。 别焦虑!作为一个刚把AI率打下来的过来人,我发现:AI的痕迹其实是有迹可循的。…

【笔记】ST 表

求区间最值:RMQ问题。 用ST表求解。递推公式:\(K=(\log (R-L+1) \div \log (2))\) 直接在 cmath 中调用,cmath 中是以 \(10\) 为底,所以用到以上换底公式。也可以预处理 \(\log\) 优化常数复杂度。 log[i]=log[i/2…