Qt中如何通过多线程修改变量?4线程累加随机值实现方法
解决Qt多线程修改全局变量的线程安全问题
你的问题核心是多线程竞态条件:a += qrand()看似一行代码,实际拆成了「读取a的值 → 计算a+随机数 → 写回a」三个独立步骤。当多个线程同时执行这几步时,很可能出现两个线程读到同一个初始a值,各自计算后写回,导致其中一个线程的修改被覆盖,最终结果远小于4个随机数的总和。
下面给你两种Qt中常用的可靠解决方法:
方法一:使用QMutex互斥锁
通过互斥锁保证同一时间只有一个线程能访问和修改a,彻底避免竞态冲突。
具体实现:
- 定义全局的互斥锁(和变量a绑定):
#include <QMutex> int a = 0; QMutex aMutex; // 全局互斥锁,专门保护对a的读写操作
- 修改A类的
run()函数,用锁包裹对a的修改逻辑:
void A::run() { // ... 其他业务代码 ... int randomVal = qrand(); // 手动加锁/解锁 aMutex.lock(); a += randomVal; aMutex.unlock(); // ... 其他业务代码 ... }
更推荐用QMutexLocker自动管理锁(避免忘记解锁导致死锁):
void A::run() { // ... 其他业务代码 ... int randomVal = qrand(); { QMutexLocker locker(&aMutex); // 构造时自动加锁,代码块结束时自动解锁 a += randomVal; } // ... 其他业务代码 ... }
方法二:使用QAtomicInt原子变量
Qt提供了QAtomicInt类,专门支持原子性的整数操作,不需要手动加锁,代码更简洁高效。
具体实现:
- 将全局变量a替换为
QAtomicInt:
#include <QAtomicInt> QAtomicInt a = 0; // 原子变量,所有操作都是线程安全的
- 修改
run()函数,用原子操作方法完成累加:
void A::run() { // ... 其他业务代码 ... int randomVal = qrand(); a.fetchAndAdd(randomVal); // 原子性累加,过程不会被其他线程打断 // ... 其他业务代码 ... }
fetchAndAdd()会原子性地把randomVal加到a上,返回a修改前的值,完全规避竞态问题。
额外提示:等待所有线程执行完毕
如果你需要确保所有线程都完成修改后再获取a的最终值,可以在主线程中等待每个线程结束:
A** baseThread=new A*[4]; for(int m=0;m<4;m++) { baseThread[m] = new A(); baseThread[m]->start(); } // 等待所有线程执行完成 for(int m=0;m<4;m++) { baseThread[m]->wait(); delete baseThread[m]; } delete[] baseThread; // 此时a的值就是4个随机数的准确总和 qDebug() << "最终a的值:" << a;
内容的提问来源于stack exchange,提问作者morteza ali ahmadi




