Qt多线程从基础到性能优化

一、为什么需要多线程开发

  1. 现代应用程序的性能需求

  2. CPU多核架构的有效利用

  3. 复杂任务的解耦与响应式界面保持

二、Qt线程创建四大方式

1. 继承QThread重写run()

class WorkerThread : public QThread {void run() override {// 耗时操作qDebug() << "Thread ID:" << QThread::currentThreadId();}
};// 使用
WorkerThread *thread = new WorkerThread();
thread->start();

适用场景:简单线程任务,需要快速实现

2. 使用moveToThread

QThread *thread = new QThread();
Worker *worker = new Worker();
worker->moveToThread(thread);connect(thread, &QThread::started, worker, &Worker::doWork);
connect(worker, &Worker::workDone, thread, &QThread::quit);thread->start();

优势

  • 完美契合Qt事件循环

  • 支持信号槽通信

  • 对象生命周期易管理

3. QtConcurrent高级API

QFuture<void> future = QtConcurrent::run([](){// 并行任务
});

特性

  • 自动线程池管理

  • 支持返回值获取(QFuture)

  • Map-Reduce模式支持

4. 线程池(QThreadPool)

class Task : public QRunnable {void run() override {// 任务逻辑}
};QThreadPool::globalInstance()->start(new Task());

最佳实践

  • 适合大量短期任务

  • 默认最大线程数 = CPU核心数

  • 自定义线程池配置

三、线程同步机制

1. 互斥锁(QMutex)

QMutex mutex;
int counter = 0;void increment() {QMutexLocker locker(&mutex);counter++;
}

2. 读写锁(QReadWriteLock)

QReadWriteLock lock;
void readData() {QReadLocker reader(&lock);// 读取操作
}

3. 信号量(QSemaphore)

QSemaphore sem(5); // 初始资源数void accessResource() {sem.acquire();// 使用资源sem.release();
}

4. 条件变量(QWaitCondition)

QWaitCondition condition;
QMutex mutex;// 等待方
mutex.lock();
condition.wait(&mutex);
mutex.unlock();// 唤醒方
condition.wakeAll();

四、线程通信方案

1. 信号槽机制

// 自动连接(默认)
connect(worker, &Worker::resultReady, this, &Controller::handleResult);// 队列连接(跨线程)
connect(worker, &Worker::dataUpdated,this, &Controller::updateUI, Qt::QueuedConnection);

2. 事件传递

class CustomEvent : public QEvent {
public:// 自定义事件类型和数据
};// 发送事件
QCoreApplication::postEvent(receiver, new CustomEvent());

3. 共享内存

QSharedMemory sharedMem("MySharedMemory");
sharedMem.create(1024); // 创建共享内存

五、开发注意事项

  1. GUI操作限制

    • 所有界面操作必须在主线程

    • 使用QMetaObject::invokeMethod跨线程更新UI

  2. 内存管理

    • 使用QObject的父子关系自动回收

    • 注意跨线程delete的隐患

  3. 死锁预防

    • 避免嵌套锁

    • 统一加锁顺序

    • 使用QMutex::tryLock()

  4. 资源竞争

    • 原子操作使用QAtomicInteger

    • 线程局部存储(QThreadStorage)

六、性能优化策略

  1. 线程数量控制

    • 理想数量 = CPU核心数 ± 2

    • I/O密集型可适当增加

  2. 锁粒度优化

    // 错误示例:大范围锁
    void process() {mutex.lock();// 大量无关操作mutex.unlock();
    }// 正确做法:最小临界区
    void process() {// 非临界区操作{QMutexLocker lock(&mutex);// 关键数据操作}// 后续处理
    }
  3. 任务调度优化

    • 批量处理代替频繁小任务

    • 使用生产者-消费者模式

  4. 性能分析工具

    • QElapsedTimer计时

    • 使用valgrind检测竞争

七、Qt多线程最佳实践

  1. 优先选择moveToThread方案

  2. 避免频繁线程创建/销毁

  3. 合理使用异步接口

  4. 定期进行线程安全检查

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

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

相关文章

【java】在 Java 中,获取一个类的`Class`对象有多种方式

在 Java 中&#xff0c;获取一个类的Class对象有多种方式。Class对象代表了 Java 中的一个类或接口的运行时类信息&#xff0c;可以用于反射操作。以下是获取Class对象的几种常见方法&#xff1a; 1.使用.class属性 每个类都有一个.class属性&#xff0c;可以直接获取该类的Cl…

什么是RPC通信

RPC&#xff08;Remote Procedure Call&#xff0c;远程过程调用&#xff09;通信是一种允许程序像调用本地函数一样调用远程服务器上函数的通信技术。它简化了分布式系统中的网络交互&#xff0c;隐藏了底层网络通信的复杂性&#xff0c;使开发者能够专注于业务逻辑。 一、RPC…

还是主题混合程序设计

以下是针对您现有代码的完整主题化改造方案&#xff0c;实现跨QML/Qt Widgets的阴影主题系统&#xff1a; 一、主题管理系统核心 // thememanager.h #pragma once #include <QObject> #include <QColor> #include <QMap> #include <QQmlEngine>class…

BT-Basic函数之首字母T

BT-Basic函数之首字母T 文章目录 BT-Basic函数之首字母Ttabtesttest conttest monitortest on boardstest scanworkstest shortstesthead cleanuptesthead configurationtesthead istesthead power on/offtesthead statustestjet print level istestordertestplan generationth…

7-9 趣味游戏

题目解析 在某个学校的趣味游戏活动中&#xff0c;N 名同学站成一排&#xff0c;他们的年龄恰好是 1 到 N &#xff0c;需要注意的是他们并不是按照年龄的大小排列的&#xff0c;而是随机排列的。 游戏的规则是请同学们快速计算出&#xff0c;如果在这 N 名同学的小组中&…

Hugging Face模型微调训练(基于BERT的中文评价情感分析)

文章目录 学习视频地址项目地址数据集的下载模型微调的基本概念与流程加载数据集数据集格式数据集信息 制作Dataset数据集字段数据集信息 vocab字典操作词汇表文本转换 下游任务模型设计模型训练与保存数据加载优化器训练循环 最终效果评估与测试模型加载和测试 学习视频地址 …

【蓝桥杯】十五届省赛B组c++

目录 前言 握手问题 分析 排列组合写法 枚举 小球反弹 分析 代码 好数 分析 代码 R 格式 分析 代码 宝石组合 分析 代码 数字接龙 分析 代码 拔河 分析 代码 总结 前言 主播这两天做了一套蓝桥杯的省赛题目&#xff08;切实感受到了自己有多菜&#x…

必刷算法100题之计算右侧小于当前元素的个数

题目链接 315. 计算右侧小于当前元素的 个数 - 力扣&#xff08;LeetCode&#xff09; 题目解析 计算数组里面所有元素右侧比它小的数的个数, 并且组成一个数组,进行返回 算法原理 归并解法(分治) 当前元素的后面, 有多少个比我小(降序) 我们要找到第一比左边小的元素, 这…

Hyperlane框架:下一代高性能Rust Web框架 [特殊字符]

Hyperlane框架&#xff1a;下一代高性能Rust Web框架 &#x1f680; 引言 &#x1f44b; 在当今快速发展的Web开发领域&#xff0c;性能和开发效率的平衡变得越来越重要。Hyperlane作为一个新兴的Rust Web框架&#xff0c;完美地解决了这个问题。本文将带您深入了解Hyperlane…

图像处理:使用Numpy和OpenCV实现傅里叶和逆傅里叶变换

文章目录 1、什么是傅里叶变换及其基础理论 1.1 傅里叶变换 1.2 基础理论 2. Numpy 实现傅里叶和逆傅里叶变换 2.1 Numpy 实现傅里叶变换 2.2 实现逆傅里叶变换 2.3 高通滤波示例 3. OpenCV 实现傅里叶变换和逆傅里叶变换及低通滤波示例 3.1 OpenCV 实现傅里叶变换 3.2 实现逆傅…

OpenEuler/CentOS一键部署OpenGauss数据库教程(脚本+视频)

&#x1f4cc;OpenEuler/CentOS一键安装OpenGauss数据库教程 为什么需要OpenGauss一键安装脚本&#xff1f; 手动部署OpenGauss数据库时&#xff0c;环境适配、依赖冲突等问题常让开发者头疼。尤其对新人而言&#xff0c;官方文档的配置步骤可能耗时数小时甚至引发未知报错。 …

如何解决 Hive 在创建 MySQL 表时出现乱码???的问题

1.问题描述 我们启动Hive建立一个学生students表格 使用desc students;查看表格结构时 发现有出现乱码的情况 2.解决方案 打开Hive安装机器上面的MySQL 切换到Hive数据库 执行以下命令修改字段注释字符集 mysql -u root -p123456;use hive;alter table COLUMNS_V2 modify col…

自定义组件触发饿了么表单校验

饿了么的表单控件&#xff0c;如果存在自定义组件更改了值&#xff0c;例如在el-from中存在原生input组件很有可能没法触发表单校验&#xff0c;下拉框或者弹框组件仍然是报红边框。 这是因为饿了么的输入框或者下拉框更改值的时候会自动触发表单校验&#xff0c;但是封装过后的…

架构思维:查询分离 - 表数据量大查询缓慢的优化方案

文章目录 Pre引言案例何谓查询分离&#xff1f;何种场景下使用查询分离&#xff1f;查询分离实现思路1. 如何触发查询分离&#xff1f;方式一&#xff1a; 修改业务代码&#xff1a;在写入常规数据后&#xff0c;同步建立查询数据。方式二&#xff1a;修改业务代码&#xff1a;…

Linux开发工具——make/makefile

&#x1f4dd;前言&#xff1a; 这篇文章我们来讲讲Linux开发工具——make/makefile&#xff1a; &#x1f3ac;个人简介&#xff1a;努力学习ing &#x1f4cb;个人专栏&#xff1a;Linux &#x1f380;CSDN主页 愚润求学 &#x1f304;其他专栏&#xff1a;C学习笔记&#xf…

python加载训练好的模型并进行叶片实例分割预测

要基于“GMT: Guided Mask Transformer for Leaf Instance Segmentation”进行代码复现&#xff0c;可按照以下步骤利用Python实现&#xff1a; 环境配置 克隆仓库&#xff1a;在终端中使用git clone https://github.com/vios-s/gmt-leaf-ins-seg.git命令&#xff0c;将项目代…

AI平台初步规划实现和想法

要实现一个类似Coze的工作流搭建引擎&#xff0c;可以结合SmartEngine作为后端工作流引擎&#xff0c;ReactFlow作为前端流程图渲染工具&#xff0c;以及Ant Design作为UI组件库。以下是实现的步骤和关键点&#xff1a; ### 1. 后端工作流引擎&#xff08;SmartEngine&#xf…

Pycharm 启动时候一直扫描索引/更新索引 Update index/Scanning files to index

多个项目共用一个虚拟环境&#xff0c;有助于加快PyCharm 启动吗 chatgpt 4o认为很有帮助&#xff0c;gemini 2.5pro认为没鸟用&#xff0c;我更认可gemini的观点。不知道他们谁在一本正经胡说八道。 -------- 打开pycharm的时候&#xff0c;下方的进度条一直显示在扫描文件…

dify新版本1.1.3的一些问题

本人使用window版本上构建dify&#xff0c;采用docker方法启动 1、拉取镜像问题 windows上更改拉取镜像仓库地址 优化加速参考&#xff1a;青春不留白/Docker-hub 如果还是拉取比较慢的话&#xff0c;建议科学上网解决。 2、启动问题 发生报错Dify:failed to init dify plu…

4.2-3 fiddler抓取手机接口

安卓&#xff1a; 长按手机连接的WiFi&#xff0c;点击修改网络 把代理改成手动&#xff0c;服务器主机选择自己电脑的IP地址&#xff0c;端口号为8888&#xff08;在dos窗口输入ipconfig查询IP地址&#xff0c;为ipv4&#xff09; 打开手机浏览器&#xff0c;输入http://自己…