Qt 一次性把多线程实现同步方式说清楚
概念(为何需要同步)1.多个线程同时读写共享资源(全局/静态内存变量、堆内存动态分配对象、文件/IO/网络句柄、外设资源等),执行顺序不确定,导致数据错乱、崩溃;2.同步主要是为了保证共享资源互斥访问、线程等待/唤醒、有序执行;3.测试(没添加同步)main.cpp#include QCoreApplication #include QThread #include QMutex #include QMutexLocker #include QReadWriteLock #include QReadLocker #include QWriteLocker #include QWaitCondition #include QSemaphore #include QAtomicInt #include QAtomicPointer #include QAtomicInteger #include QtConcurrent/QtConcurrent #include QDebug #include atomic int g_count_mutex 0; void mutexTask() { qDebug() 子线程ID: QThread::currentThreadId(); for (int i 0; i 10000; i) { g_count_mutex; QThread::msleep(1); } } void demo_QMutex() { g_count_mutex 0; QFuturevoid t1 QtConcurrent::run(mutexTask); QFuturevoid t2 QtConcurrent::run(mutexTask); t1.waitForFinished(); t2.waitForFinished(); qDebug() QMutex 最终计数: g_count_mutex; } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); demo_QMutex(); return 0; //return a.exec(); }一、方式11.QMutex基础互斥锁:1)保证同一时间仅一个线程进入临界区保护共享变量读写;2)API:--lock(): 加锁,已被占用则阻塞线程,直到释放;--tryLock(): 非阻塞尝试加锁,获取成功返回true,失败立即返回false;--tryLock(int timeout): 带超时,超时内拿不到锁返回false;--unlock(): 释放锁,必须与lock成对调用。2.测试main.cpp//全局共享变量 互斥锁 QMutex g_mutex; int g_count_mutex 0; void mutexTask() { qDebug() 子线程ID: QThread::currentThreadId(); for (int i 0; i 10000; i) { g_mutex.lock(); g_count_mutex; g_mutex.unlock(); } } void demo_QMutex() { g_count_mutex 0; QFuturevoid t1 QtConcurrent::run(mutexTask); QFuturevoid t2 QtConcurrent::run(mutexTask); t1.waitForFinished(); t2.waitForFinished(); qDebug() QMutex 最终计数: g_count_mutex; } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); demo_QMutex(); return 0; //return a.exec(); }二、方式21.QMutexLocker(RAII 自动锁):1)栈对象构造时自动lock,离开作用域(return/异常/花括号结束)自动unlock,无需手动释放;2.测试main.cpp#include QCoreApplication #include QThread #include QMutex #include QMutexLocker #include QReadWriteLock #include QReadLocker #include QWriteLocker #include QWaitCondition #include QSemaphore #include QAtomicInt #include QAtomicPointer #include QAtomicInteger #include QtConcurrent/QtConcurrent #include QDebug #include atomic //全局共享变量 互斥锁 QMutex g_mutex; int g_count_mutex 0; void mutexLockerTask() { qDebug() 子线程ID: QThread::currentThreadId(); for (int i 0; i 10000; i) { QMutexLocker locker(g_mutex); //RAII自动加锁/解锁 g_count_mutex; //QThread::msleep(1); } } void demo_QMutexLocker() { g_count_mutex 0; QFuturevoid t1 QtConcurrent::run(mutexLockerTask); QFuturevoid t2 QtConcurrent::run(mutexLockerTask); t1.waitForFinished(); t2.waitForFinished(); qDebug() QMutexLocker 最终计数: g_count_mutex; } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); demo_QMutexLocker(); return 0; //return a.exec(); }三、方式31.QReadWriteLock读写锁:1)多个线程可同时获取读锁(读和读不冲突);2)写锁独占: 有线程持有读锁/写锁时,写线程阻塞持有写锁时,所有读写线程阻塞;3)配套RAII工具: QReadLocker、QWriteLocker;4)API:--lockForRead(): 获取读锁;--lockForWrite(): 获取写锁;--tryLockForRead(int t 0);--tryLockForWrite(int t 0);--unlock();2.测试main.cpp#include QCoreApplication #include QThread #include QMutex #include QMutexLocker #include QReadWriteLock #include QReadLocker #include QWriteLocker #include QWaitCondition #include QSemaphore #include QAtomicInt #include QAtomicPointer #include QAtomicInteger #include QtConcurrent/QtConcurrent #include QDebug #include atomic QReadWriteLock g_rwLock; int g_data_rw 0; //读线程 void readTask() { for (int i 0; i 100; i) { QReadLocker lock(g_rwLock); //读锁允许多线程同时读 qDebug() 读值: g_data_rw; QThread::msleep(5); } } //写线程 void writeTask() { for (int i 0; i 100; i) { QWriteLocker lock(g_rwLock); //写锁独占访问 g_data_rw; qDebug() 写入值: g_data_rw; QThread::msleep(10); } } void demo_QReadWriteLock() { g_data_rw 0; QFuturevoid r1 QtConcurrent::run(readTask); QFuturevoid r2 QtConcurrent::run(readTask); QFuturevoid w1 QtConcurrent::run(writeTask); r1.waitForFinished(); r2.waitForFinished(); w1.waitForFinished(); qDebug() QReadWriteLock 最终值: g_data_rw; } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); demo_QReadWriteLock(); return 0; //return a.exec(); }四、方式41.QWaitCondition条件变量:1)线程主动阻塞等待某个条件成立,其他线程修改条件后唤醒等待线程,实现线程间等待/通知,必须配合QMutex使用;2)API:--wait(QMutex*, unsigned long timeout): 释放锁,阻塞等待唤醒,超时自动返回;--wakeOne(): 随机唤醒1个等待线程;--wakeAll(): 唤醒全部等待线程。2.测试main.cpp#include QCoreApplication #include QThread #include QMutex #include QMutexLocker #include QReadWriteLock #include QReadLocker #include QWriteLocker #include QWaitCondition #include QSemaphore #include QAtomicInt #include QAtomicPointer #include QAtomicInteger #include QtConcurrent/QtConcurrent #include QDebug #include atomic QMutex g_condMutex; QWaitCondition g_cond; int g_buffer 0; bool g_hasData false; //消费者 void consumerTask() { QMutexLocker lock(g_condMutex); // while 循环防止虚假唤醒 while (!g_hasData) { g_cond.wait(g_condMutex); } qDebug() 消费数据: g_buffer; g_hasData false; g_cond.wakeOne(); //通知生产者可以继续生产 } //生产者 void producerTask(int val) { QMutexLocker lock(g_condMutex); while (g_hasData) { g_cond.wait(g_condMutex); } g_buffer val; g_hasData true; qDebug() 生产数据: g_buffer; g_cond.wakeOne(); } void demo_QWaitCondition() { g_hasData false; QFuturevoid consumer QtConcurrent::run(consumerTask); QThread::msleep(100); QFuturevoid producer QtConcurrent::run(producerTask, 999); consumer.waitForFinished(); producer.waitForFinished(); } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); demo_QWaitCondition(); return 0; //return a.exec(); }五、方式51.QSemaphore信号量:1)内置计数器,控制有限资源的并发访问,本质是带计数的条件变量;2)API:--acquire(n): 申请n个资源,资源不足则阻塞;--release(n): 释放n个资源,计数器 n;--available(): 返回当前剩余资源数量。2.测试main.cpp#include QCoreApplication #include QThread #include QMutex #include QMutexLocker #include QReadWriteLock #include QReadLocker #include QWriteLocker #include QWaitCondition #include QSemaphore #include QAtomicInt #include QAtomicPointer #include QAtomicInteger #include QtConcurrent/QtConcurrent #include QDebug #include atomic QSemaphore g_sem(2); // 最多允许2个线程同时进入临界区 void semTask(int id) { g_sem.acquire(); // 占用1个资源超出上限则阻塞 qDebug() 任务 id 进入临界区; QThread::msleep(1000); qDebug() 任务 id 离开临界区; g_sem.release(); // 释放资源 } void demo_QSemaphore() { QFuturevoid t1 QtConcurrent::run(semTask, 1); QFuturevoid t2 QtConcurrent::run(semTask, 2); QFuturevoid t3 QtConcurrent::run(semTask, 3); QFuturevoid t4 QtConcurrent::run(semTask, 4); t1.waitForFinished(); t2.waitForFinished(); t3.waitForFinished(); t4.waitForFinished(); qDebug() QSemaphore 全部任务结束; } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); demo_QSemaphore(); return 0; //return a.exec(); }六、方式61.QBasicAtomic/std::atomic原子变量(无锁同步):1)无锁,CPU 硬件指令保证单个变量原子读写,不需要加锁,性能最高;2)仅支持基础类型int、long、指针。2.测试main.cpp#include QCoreApplication #include QThread #include QMutex #include QMutexLocker #include QReadWriteLock #include QReadLocker #include QWriteLocker #include QWaitCondition #include QSemaphore #include QAtomicInt #include QAtomicPointer #include QAtomicInteger #include QtConcurrent/QtConcurrent #include QDebug #include atomic //Qt原子变量 QBasicAtomicInt g_qtAtomic Q_BASIC_ATOMIC_INITIALIZER(0); //C标准原子变量 std::atomicint g_stdAtomic{0}; void atomicTask() { for (int i 0; i 5000; i) { g_qtAtomic.ref(); // Qt原子自增 g_stdAtomic.fetch_add(1);// C原子自增 } } void demo_Atomic() { g_qtAtomic 0; g_stdAtomic 0; QFuturevoid t1 QtConcurrent::run(atomicTask); QFuturevoid t2 QtConcurrent::run(atomicTask); t1.waitForFinished(); t2.waitForFinished(); qDebug() QBasicAtomicInt 计数: g_qtAtomic.load(); qDebug() std::atomic 计数: g_stdAtomic.load(); } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); demo_Atomic(); return 0; //return a.exec(); }七、开发工具及Qt版本开发工具:Qt Creator 4.10.2Qt版本:Qt_5_12_6

相关新闻

成都算法备案技术指南:备案流程与材料清单

成都算法备案技术指南:备案流程与材料清单

根据《互联网信息服务算法推荐管理规定》(国家网信办等四部委联合发布)和《互联网信息服务深度合成管理规定》,2026年算法备案已成为AI和相关企业的法定合规义务。截至2026年3月,全国完成算法备案的企业不足1万家——大量企业在需…

2026/7/22 9:41:35阅读更多 →
合肥专业的餐饮点餐小程序,你知道哪家好?

合肥专业的餐饮点餐小程序,你知道哪家好?

引言在合肥,寻找一款专业的餐饮点餐小程序至关重要。一款优质的点餐小程序能提升餐厅运营效率,改善顾客用餐体验。微客智联便是这样一款值得推荐的产品。微客智联的优势全渠道订单归集微客智联系统聚合扫码点餐、小程序外卖、堂食收银、主流外卖平台等全…

2026/7/22 9:39:35阅读更多 →
成都高端整装装修公司测评,推荐岚庭集团的“呼声“凭什么那么高?

成都高端整装装修公司测评,推荐岚庭集团的“呼声“凭什么那么高?

在成都待久了你会发现,这座城市的人对“住”这件事,有着超乎寻常的讲究。但讲究归讲究,真到了要装修的时候,大部分人反而变得格外谨慎——甚至有点怕。原因很简单。身边随便一问,十个装修过的朋友里,七八个…

2026/7/22 9:39:35阅读更多 →
Tiva™ TM4C1299 LCD控制器寄存器配置与双缓冲驱动实战

Tiva™ TM4C1299 LCD控制器寄存器配置与双缓冲驱动实战

1. 项目概述与核心价值在嵌入式图形界面开发中,驱动一块LCD屏往往是项目从“能跑”到“好用”的关键一步。很多开发者拿到一块新的显示屏,照着厂家给的初始化代码配一遍,画面能出来就觉得万事大吉。但一旦遇到闪屏、撕裂、或者需要动态更新复…

2026/7/22 10:53:45阅读更多 →
USB设备控制器握手协议与FIFO管理核心解析

USB设备控制器握手协议与FIFO管理核心解析

1. USB设备控制器握手协议与FIFO管理核心解析在嵌入式系统开发中,USB接口几乎是连接PC与外部设备的标配。无论是数据采集卡、工业控制器还是消费电子,稳定可靠的USB通信都是产品成功的关键。很多开发者初次接触USB设备控制器编程时,往往会被其…

2026/7/22 10:53:45阅读更多 →
Cursor IDE:AI编程时代的智能开发工具实战指南

Cursor IDE:AI编程时代的智能开发工具实战指南

1. Cursor是什么?为什么开发者都在用?作为一名长期使用JetBrains全家桶的老程序员,我最初对Cursor这个新兴IDE持怀疑态度。直到去年参与一个紧急项目时,被团队强制要求使用Cursor协作,才真正体会到它的威力。Cursor本质…

2026/7/22 10:53:45阅读更多 →
分拣效率决定利润!菜东家智能分拣系统,搞定生鲜配送核心难题

分拣效率决定利润!菜东家智能分拣系统,搞定生鲜配送核心难题

做生鲜配送,分拣是核心命脉,也是最大成本黑洞。很多配送老板都有同款困扰:凌晨订单堆积、纸质单据混乱、人工分拣靠眼力和经验,错分、漏分、串单频发;新人上手慢、熟手人工成本高,旺季爆单人手不够、淡季人…

2026/7/22 10:53:45阅读更多 →
查看torch 的内置依赖约束、版本相关和下载链接和 onnx-runtime-gpu 版本

查看torch 的内置依赖约束、版本相关和下载链接和 onnx-runtime-gpu 版本

由于报错引发以下系列操作:一. 确定torch内置依赖约束 cuda-toolkit13.0.2 的依赖关系 不是写在 PyTorch 官网文档里的,而是在 wheel 包内部的 METADATA 文件 中的。它是 pip 在安装时自动读取的包元数据,属于 NVIDIA 打包 nvidia-cuda-* 系…

2026/7/22 10:53:44阅读更多 →
AI Agent与ChatGPT的本质差异及架构解析

AI Agent与ChatGPT的本质差异及架构解析

1. 为什么Agent不是ChatGPT?本质差异解析 第一次接触AI Agent概念的开发者,常会陷入一个典型误区——把Agent简单理解为"升级版ChatGPT"。这种认知偏差会导致后续技术选型和架构设计出现方向性错误。让我们从三个维度拆解二者的本质区别&#…

2026/7/22 10:51:44阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/22 0:53:59阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/22 0:53:59阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/22 0:53:59阅读更多 →
中小企业小程序开发公司怎么选:预算、上手和售后避坑指南

中小企业小程序开发公司怎么选:预算、上手和售后避坑指南

中小企业做小程序,最常见的矛盾是预算有限,但又不希望功能太单薄;没有技术团队,但又希望后续能自己运营;想快速上线,又担心隐性收费和售后失联。选型时如果只看“低价套餐”或“案例数量”,很容…

2026/7/22 0:01:17阅读更多 →
GEO优化如何沉淀长期内容资产?广拓时代谈AI搜索时代的内容ROI

GEO优化如何沉淀长期内容资产?广拓时代谈AI搜索时代的内容ROI

企业做营销,最怕钱花完了,资产没有留下。 效果广告能带来一段时间的曝光,但预算停止后,流量往往也随之停止。短视频内容可能在几天内冲高,也可能很快沉下去。AI搜索时代,企业需要重新思考一个问题&#xff…

2026/7/22 0:01:17阅读更多 →
Agent 终态判定:何时该停止思考、给出最终回复

Agent 终态判定:何时该停止思考、给出最终回复

Agent 终态判定:何时该停止思考、给出最终回复 一、你的 Agent 在"再想想"的循环里绕了 12 轮,用户已经关窗口了 Agent 与人最大的区别是:人知道什么时候该停下来给答案,Agent 会一直"想"下去。你给 Agent 接…

2026/7/22 0:01:17阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/21 22:53:50阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/21 18:53:30阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/21 18:53:30阅读更多 →