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

相关推荐
用户805533698035 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner5 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz10 天前
QML Hello World 入门示例
qt
xcyxiner13 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner13 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner14 天前
DicomViewer (添加模型类)3
qt
xcyxiner14 天前
DicomViewer (目录调整) 2
qt
xcyxiner14 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
桥田智能16 天前
桥田智能 QT-650S:面向白车身焊装的 800kg 重载快换解决方案
开发语言·qt·系统架构
森G16 天前
75、服务器源码解析---------云视频服务项目
linux·服务器·网络·c++·qt