Qt 的多线程

Qt 中的多线程主要用于处理耗时操作,避免阻塞主线程(UI 线程),从而提高程序的响应性和运行效率。以下是 Qt 多线程的相关技术总结:

常见的多线程实现方式

  • 继承 QThread 类 :最基础的实现方式,具体步骤为继承 QThread 类,重写其 run() 函数,在 run() 函数中编写线程要执行的代码,然后调用 start() 函数启动线程。例如:

    • 定义一个自定义线程类 CameraThread,继承自 QThread,在 run() 函数中进行相机数据采集等耗时操作,并通过信号将采集到的数据传递给主线程。

    • 在主线程中创建该线程对象,连接线程的信号与主线程的槽函数,启动线程后,子线程中的 run() 函数开始执行,主线程则继续运行,不会被耗时操作阻塞。

  • Worker + moveToThread 模式 :推荐使用的方式,更加灵活。其实现步骤为先创建一个工作类(QObject),定义该类的具体工作内容;再创建一个 QThread 对象;然后通过 moveToThread() 方法将工作对象移动到子线程;接着连接子线程的启动信号与工作对象的任务槽函数,以及工作对象的任务完成信号与主线程的槽函数,最后启动子线程。

    • 例如,定义一个 CameraWorker 类,在其中定义数据采集任务的槽函数 doWork(),以及任务完成后的信号 frameReady。在主线程中创建 QThread 对象和 CameraWorker 对象,将 CameraWorker 对象移动到子线程,连接相关信号与槽函数,启动子线程后,CameraWorker 对象的 doWork() 函数在子线程中执行,采集到的数据通过信号传递给主线程进行 UI 更新。

  • 使用 QThreadPool 线程池 :适用于需要管理多个线程的场景,可避免频繁创建和销毁线程带来的开销。需创建一个继承自 QRunnable 的任务类,并重写其 run() 函数,在该函数中定义任务的具体执行逻辑,然后将任务对象提交到全局线程池中执行。

    • 比如,定义一个 MyTask 类继承自 QRunnable,在 run() 函数中实现相应的任务代码,接着在主线程中创建 MyTask 对象,并通过 QThreadPool::globalInstance()->start(task) 将任务提交到线程池,线程池会自动分配线程来执行任务。

  • 利用 QtConcurrent 框架 :提供了更高级的多线程编程方式,无需显式地创建和管理线程。其常用的函数有 QtConcurrent::run()、QtConcurrent::map()、QtConcurrent::filter() 等,可用于并行计算、数据处理等功能。

    • 例如,使用 QtConcurrent::run() 函数可以在一个新线程中执行一个普通函数或成员函数,该函数会自动在后台线程中运行,无需手动创建线程和处理线程同步等问题。

多线程的核心原理

  • 事件循环 :每个线程都有自己的事件循环,用于处理该线程中的事件,如信号槽调用、定时器事件等。主线程的事件循环由 QApplication 或 QCoreApplication 启动,子线程可以通过调用 exec() 函数启动事件循环。

  • 信号槽通信 :是 Qt 多线程间通信的核心机制。跨线程时,信号会被自动转为 “事件” 放入目标线程的事件循环中执行,从而实现线程间的安全通信。例如,子线程通过发出信号将采集到的数据传递给主线程,主线程接收到信号后在对应的槽函数中更新 UI。

多线程开发的注意事项

  • 避免直接操作 UI :子线程不能直接操作 UI 控件,所有 UI 操作都必须通过信号槽传递到主线程中进行。

  • 线程安全 :如果多个线程需要访问同一变量或资源,需使用 QMutex 或 QReadWriteLock 等互斥锁来保护共享数据,避免出现竞态条件和数据不一致的问题。

  • 正确退出线程 :应使用标志位控制循环退出,而不是强制调用 terminate() 函数,以确保线程能够安全、优雅地终止。并在 QThread::finished 信号中删除相关对象,避免内存泄漏。

  • 信号槽连接类型 :需要明确信号槽的连接类型,跨线程时建议使用 Qt::QueuedConnection,同线程时可使用 Qt::DirectConnection,默认情况下 Qt 会自动判断连接类型。

多线程的应用场景

  • UI 响应优化 :将耗时的计算、数据处理、文件读写等操作放到子线程中执行,确保主线程能够快速响应用户的操作,保持界面的流畅性。

  • 异步数据加载 :在网络应用中,数据的加载和传输通常需要较长时间,通过多线程可以实现异步加载数据,避免阻塞 UI,提升用户体验。

  • 并发处理任务 :在需要同时处理多个任务时,如同时处理多个设备的数据采集、多个文件的压缩或解压缩等,可以使用多线程来提高任务的执行效率。

  • 图形图像处理 :对于复杂的图形图像处理任务,如图像的渲染、滤镜效果的实现等,可以将这些任务分配到多个线程中并行处理,以加速处理过程。

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

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

相关文章

基于ITcpServer/IHttpServer框架的HTTP服务器

https://www.cnblogs.com/MuZhangyong/p/16839231.html 在基于ITcpServer/IHttpServer框架的HTTP服务器实现中,OnBody方法主要用于接收HTTP请求体数据,而触发HTTP响应通常是在OnMessageComplete方法中完成。以下是完整的响应触发机制说明: sequenceDiagramClient->>…

Windows 下 Qt 项目配置 FFmpeg 简明指南

一、作用 在qt项目中配置ffmpeg库 二、步骤 1、直接使用已经编译好的ffmpeg库文件,分为win32版本和win64版本; 2、win32版本下载地址:https://github.com/sudo-nautilus/FFmpeg-Builds-Win32/releases/tag/latest 3、win64版本下载地址&a…

Attu下载 Mac版与Win版

通过Git地址下载 Mac 版选择对于的架构进行安装 其中遇到了安装不成功,文件损坏等问题 一般是两种情况导致 1.安装版本不对 2.系统权限限制 https://www.cnblogs.com/similar/p/11280162.html打开terminal执行以下命令 sudo spctl --master-disable安装包Git下载地…

SpringBoot3集成Oauth2.1——5资源地址配置

配置问题说明 如下所示,代码配置了两个,过滤器,一个是资源保护,一个是不保护。 /** Description: 配置需要保护的资源* author: 胡涛* mail: hutao_2017aliyun.com* date: 2025年5月23日 下午2:28:20*/BeanOrder(2)public Securi…

Python urllib.parse 模块中的 urljoin 方法

Python urllib.parse 模块中的 urljoin 方法 urljoin 是 Python 标准库中 urllib.parse 模块的一个方法,用于将基础 URL 和相对路径拼接成完整的 URL。它会根据传入的基础 URL 自动处理协议、域名以及路径的部分匹配逻辑。 以下是关于该方法的具体说明和示例&…

AI大模型和SpringAI简介

一、Spring AI 简介 SpringAI整合了全球(主要是国外)的大多数大模型,而且对于大模型开发的三种技术架构都有比较好的封装和支持,开发起来非常方便。 不同的模型能够接收的输入类型、输出类型不一定相同。SpringAI根据模型的输入…

在TIA 博途中下载程序时找不到对应的网卡怎么办?

1. 检查物理连接 确认网线已正确连接PLC和PC,接口指示灯正常。 尝试更换网线或交换机端口,排除硬件故障。 2. 确认网卡驱动已安装 设备管理器检查: 右键点击“此电脑” → “管理” → “设备管理器”。 展开“网络适配器”,确…

Zabbix实践!客户端自动发现

在线答疑:乐维社区 一、客户端状态检查 1.检查客户端的zabbix-agent2是否正常 [rootnode1 ~]# systemctl is-active zabbix-agent2.service active 2.从服务端检查是否可以获得客户端信息 [rootIT-01 ~]# zabbix_get -s ‘192.168.200.135’ -p 10050 -k ‘agent.p…

动态规划中的 求“最长”、“最大收益”、“最多区间”、“最优策略” 双重 for + 状态转移

以最长递增子序列为例 🎯 首先明确目标 以最长上升子序列(LIS)为例,假设输入是: nums : []int{10, 9, 2, 5, 3, 7, 101, 18}我们定义: dp[i]:以 nums[i] 为结尾的最长上升子序列长度目标&…

SEO关键词与长尾词高效布局

内容概要 在SEO优化实践中,关键词布局的科学性与系统性直接影响流量的获取效率与可持续性。本文以核心关键词筛选为起点,结合长尾词挖掘工具与语义关联分析技术,逐步构建覆盖用户全搜索场景的内容矩阵。通过金字塔结构模型,实现高…

考研数一公式笔记

考研数学(一)核心结论与易错点详细笔记 第一部分:高等数学 一、函数、极限、连续 (一) 重要结论与公式 等价无穷小替换 (仅限乘除运算,极限过程为 x → 0 或某特定值导致因子→0): sin x ~ x tan x ~ x arcsin x …

Debezium TableSchemaBuilder详解

Debezium TableSchemaBuilder详解 1. 类的作用与功能 1.1 核心作用 TableSchemaBuilder是Debezium中负责构建表Schema的核心类,主要功能包括: Schema构建:将数据库表结构转换为Kafka Connect的Schema定义主键处理:生成表的主键Schema值Schema处理:生成表的非主键字段Sc…

49 python Matplotlib之Pandas 数据可视化

Pandas 是 Python 中用于数据处理的核心库,其内置了基于 Matplotlib 的可视化功能,可通过 DataFrame.plot() 和 Series.plot() 方法快速生成常见图表,无需手动编写绘图代码,大幅提升效率。 一、Pandas 核心绘图方法 基础语法如下:该代码为伪代码,仅做语法说明,无法执行…

《微服务架构设计模式》笔记

思维导图 1-3章 4-6 章 5-13 章 资料 配套代码仓库:https://github.com/microservices-patterns/ftgo-application 作者网站:https://microservices.io/

手写一个简单的线程池

手写一个简单的线程池 项目仓库:https://gitee.com/bossDuy/hand-tearing-thread-pool 基于一个b站up的课程:https://www.bilibili.com/video/BV1cJf2YXEw3/?spm_id_from333.788.videopod.sections&vd_source4cda4baec795c32b16ddd661bb9ce865 理…

手机打电话时由对方DTMF响应切换多级IVR语音菜单(完结)

手机打电话时由对方DTMF响应切换多级IVR语音菜单(完结) --本地AI电话机器人 上一篇:手机打电话时由对方DTMF响应切换多级IVR语音菜单(话术脚本与实战) 下一篇:编写中 一、前言 经过前面几个篇章的详细阐…

Android.mk解析

一、变量说明: 1.LOCAL_PATH:= $(call my-dir) 此行代码在Android.mk的开头,用于给出当前文件的路径 LOCAL_PATH 用于在开发树中查找源文件 宏函数’my-dir’, 由编译系统提供,用于返回当前路径(即包含Android.mk file文件的目录) 2.LOCAL_PACKAGE_NAME := SecSettings …

ip地址改了网络还能用吗?ip地址改了有什么后果

当用户发现自己的网络出现异常时,常常会疑惑:如果IP地址被更改,网络是否还能正常使用?要解答这个问题,需要从IP地址的作用、修改方式以及网络配置等多个角度来分析。 一、IP地址的作用 IP地址是设备在网络中的唯一标识…

Python-Django系列—日志

Python 程序员通常会在其代码中使用 print() 作为一种快速和方便的调试工具。使用日志框架只比这多花一点点工夫,但更加优雅和灵活。除了用于调试之外,日志还可以为您提供有关应用程序状态和健康状况的更多信息,而且这些信息结构更清晰。 一…

ArcGIS Pro对图斑进行等比例、等面积、等宽度的分割

ArcGIS全系列实战视频教程——9个单一课程组合系列直播回放_arcgis视频教程我要自学网-CSDN博客 4大遥感软件!遥感影像解译!ArcGISENVIErdaseCognition_遥感解译软件-CSDN博客 今天介绍一下ArcGIS Pro对图斑进行等比例、等面积、等宽度的分割&#xff0…