Qt环境下普通变量与原子变量的区别与联系

一、定义

1.普通变量

int、bool、double、自定义变量

读写是拆分多条CPU微指令,不是一次性完成。

2.原子变量

std::atomic、QAtomicInteger、QAtomicBoolean

硬件层级一次性完整读写,中途不会被其他线程打断。

二、核心区别

1、执行指令

  • 普通变量

赋值/自增是多步指令,例: a++

1)从内存读a到CPU

2)CPU计算+1

3)写回内存

多线程会穿插插队,数据覆盖错乱。

​- 原子变量

a++ 整条指令不可拆分,执行中其他线程强制阻塞,不会插队。

2、多线程安全

  • 普通变量:多线程同时读写=数据竞争、脏数据、程序崩溃

​- 原子变量:天生线程安全,无需加锁

3、内存排序(指令重排)

  • 普通变量:编译器/CPU会乱序优化指令,多线程逻辑错乱

​- 原子变量:禁止指令重排,执行顺序固定

4、性能

1)普通变量:速度最快,无任何限制

2)原子变量:比普通慢一点、比mutex锁快非常多

5、使用范围

  • 普通变量:所有类型、结构体、字符串、对象都能用

  • 原子变量:只支持int、bool、long基础简单类型,结构体不可用

三、联系

1.本质都是内存存放的数据,占用内存方式一致。

2.原子变量是给普通变量加硬件防护buff。

3.都是用来存数值、状态标记。

速度:普通变量>原子变量>互斥锁mutex

安全:mutex>原子变量>普通变量

四、使用场景划分

1.单纯状态标记、开关、计数、循环标志

👉用原子变量,无锁高效

2.字符串、结构体、多步复杂赋值

👉普通变量+QMutex互斥锁

3.单线程所有变量全部用普通变量,无区别。

五 结构体变量多个线程的互斥操作

添加头文件 #include <QMutex>

// 复杂结构体互斥示例

struct MyData {

int a;

QString s; // 非平凡拷贝

};

MyData shared_data;

QMutex data_mutex; // 保护锁

void thread_safe_write() {

QMutexLocker locker(&data_mutex); // 自动加锁/解锁

shared_data.a = 20;

shared_data.s = "hello";

}

void thread_safe_read() {

QMutexLocker locker(&data_mutex);

qDebug() << shared_data.a << shared_data.s;

}

复杂结构体(含QString/指针) 一般采用 QMutex + QMutexLocker组合使用(安全、通用)。

注意:不需要为每个线程单独定义QMutex。

1)锁是保护【共享数据】的,不是保护【线程】的。

​2) 一份共享数据 → 只需要一把锁。

​3.)所有访问这份数据的线程,都共用这一把锁。

相关推荐
charlie1145141911 天前
现代Qt开发教程(新手篇)2.3——QImage、QPixmap、QIcon 图像处理基础
开发语言·图像处理·qt
AoDeLuo1 天前
SOEM2.0编译与Qt调用
qt·机器视觉
大树学长1 天前
【QT开发】Windows 10 + Qt 5.15.2 手动编译安装 Qt OPC UA 模块完整记录
开发语言·windows·qt
小短腿的代码世界1 天前
Qt低级网络编程与零拷贝技术在高频交易中的应用:从QTcpSocket到共享内存的全链路优化
开发语言·网络·qt
qq_401700411 天前
Qt 自定义无边框窗口:标题栏、拖拽移动与缩放
开发语言·qt
xiaoye-duck1 天前
Qt 信号与槽深度解析:connect 用法、自定义信号槽与 Lambda 实战
开发语言·qt
郝学胜-神的一滴1 天前
Qt 高级开发 008: 使用QSetting记住上次打开路径
开发语言·c++·qt·开源软件
W.W.H.1 天前
Qt 应用防多开:极简单例方案
开发语言·qt·单例模式·共享内存
qq_401700412 天前
Qt 中获取程序路径、用户目录、桌面路径等常用特殊路径
开发语言·qt
LostSpeed2 天前
QT5 - 添加Astyle外部格式化工具
qt·astyle