尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
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
RELATED

相关推荐

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

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

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

📅 2026/8/23 20:42:16
客运站管控·静态孪生全面升级

客运站管控·静态孪生全面升级

客运站管控静态孪生全面升级技术方案新增增强版:透镜建筑透视|车库车辆动态感知|车位级管控一、项目概述当前多数汽车客运站数字孪生系统仍停留在静态三维模型展示层面,建筑、场站、发车区、安检区、地下车库、车辆库房模型长期固…

📅 2026/9/14 0:33:20
C语言指针:内存操作与高效编程的核心技术

C语言指针:内存操作与高效编程的核心技术

1. 指针的本质与内存模型 指针本质上就是一个存储内存地址的变量。在32位系统中,指针占用4字节空间;在64位系统中则占用8字节。这个特性决定了指针能够访问系统可寻址的全部内存空间。 理解指针必须从计算机内存结构开始。我们可以把内存想象成一个巨大…

📅 2026/9/8 9:52:19
MORE NEWS

更多资讯

📰

HCR6679升压芯片峰值电流与标称电流本质区别解析

1. 从“标称3A”到“实测10A”:一场关于升压芯片电流认知的彻底纠偏你拆开一块二手升压模块,看到芯片丝印写着HCR6679,背面标注“输出3A”,心里刚松一口气——这板子应该够用。结果一接上5V输入、12V/2A负载,示波器探头…

📰

Qwen-Agent 配置完全指南:从 LLM 后端到工具系统的参数详解与实战

Qwen-Agent 配置完全指南:从 LLM 后端到工具系统的参数详解与实战 【免费下载链接】Qwen-Agent Agent framework and applications built upon Qwen>3.0, featuring Function Calling, MCP, Code Interpreter, RAG, Chrome extension, etc. 项目地址: https://…

📰

低压无刷水泵驱动芯片选型五大硬杠杠解析

1. 为什么整机厂一提“低压无刷水泵驱动芯片”就头疼?——从三个真实产线故障说起低压无刷水泵,现在几乎成了智能马桶、即热净水器、车载冰箱、小型医疗输液泵、宠物饮水机这些产品的标配动力单元。但凡做过整机量产的工程师都清楚:芯片选错&…

📰

TDengine 3.4.1.6 版本发布解析:数据接入、时区处理与稳定性增强全指南

TDengine 3.4.1.6 版本发布解析:数据接入、时区处理与稳定性增强全指南 【免费下载链接】TDengine High-performance, scalable time-series database designed for Industrial IoT (IIoT) scenarios 项目地址: https://gitcode.com/GitHub_Trending/tde/TDengine…

📰

VictoriaMetrics 的 DigitalOcean Marketplace 发布指南:Packer 镜像构建与 Kubernetes 1-Click App 上架全流程

VictoriaMetrics 的 DigitalOcean Marketplace 发布指南:Packer 镜像构建与 Kubernetes 1-Click App 上架全流程 【免费下载链接】VictoriaMetrics VictoriaMetrics: fast, cost-effective monitoring solution and time series database 项目地址: https://gitco…

📰

基于Python的招聘数据分析以及可视化-计算机毕业设计源码+LW文档

1课题背景及研究意义1.1课题背景自从互联网技术迅猛发展, 以及数字经济时期光临后, 通过网络进行的招聘已然变成企业跟求职者相互间的主要交流途径。像是智联招聘、BOSS直聘等占据主导地位有着众多求职者及招聘方使用的就业找工作选取人员任用筛选的网页平台每天都会产生数量无…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬