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.)所有访问这份数据的线程,都共用这一把锁。

相关推荐
Jun62610 小时前
QT(12)-制作lib库
开发语言·qt
努力努力再努力wz14 小时前
【内存管理与高并发内存池系列】从 mmap 到 malloc:文件映射、匿名映射与 glibc 内存分配机制详解
linux·c语言·数据结构·数据库·c++·qt·链表
JdSnE27zv14 小时前
Qt 操作SQLite数据库
数据库·qt·sqlite
小短腿的代码世界15 小时前
QtitanRibbon 深度解析:工业级Ribbon界面框架的架构设计与自定义扩展
qt·3d·架构
Drone_xjw16 小时前
qt配置项目样式表
开发语言·qt
niuniuyi~17 小时前
QT学习笔记
笔记·qt·学习
wearegogog12317 小时前
Qt触摸屏应用实例
qt
小短腿的代码世界17 小时前
Qt D-Bus深度解析:跨进程通信高级架构与源码实现
qt·架构·系统架构
luoyayun36121 小时前
Qt + FFmpeg 实战:音频静音段检测
qt·ffmpeg·音视频·静音段检测
小短腿的代码世界1 天前
Qt Quick 3D场景导入与渲染架构深度解析:从USD到PBR材质的完整管线
qt·3d·架构