You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Qt中如何通过多线程修改变量?4线程累加随机值实现方法

解决Qt多线程修改全局变量的线程安全问题

你的问题核心是多线程竞态条件a += qrand()看似一行代码,实际拆成了「读取a的值 → 计算a+随机数 → 写回a」三个独立步骤。当多个线程同时执行这几步时,很可能出现两个线程读到同一个初始a值,各自计算后写回,导致其中一个线程的修改被覆盖,最终结果远小于4个随机数的总和。

下面给你两种Qt中常用的可靠解决方法:

方法一:使用QMutex互斥锁

通过互斥锁保证同一时间只有一个线程能访问和修改a,彻底避免竞态冲突。

具体实现:

  1. 定义全局的互斥锁(和变量a绑定):
#include <QMutex>

int a = 0;
QMutex aMutex; // 全局互斥锁,专门保护对a的读写操作
  1. 修改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类,专门支持原子性的整数操作,不需要手动加锁,代码更简洁高效。

具体实现:

  1. 将全局变量a替换为QAtomicInt
#include <QAtomicInt>

QAtomicInt a = 0; // 原子变量,所有操作都是线程安全的
  1. 修改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

火山引擎 最新活动