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

相关推荐
小短腿的代码世界12 小时前
Qt文件系统与IO深度解析:从QFile到异步文件操作
开发语言·qt
徐某人..15 小时前
基于i.MX6ULL平台的智能网关系统开发
arm开发·c++·单片机·qt·物联网·学习·arm
(Charon)17 小时前
【C++/Qt】Qt 封装 TCP 客户端底层 Network 类:连接、收发、自动测试与错误处理
服务器·网络·qt·tcp/ip
小短腿的代码世界19 小时前
QCefView深度解析:Qt应用中嵌入Chromium浏览器的终极方案
开发语言·qt
小短腿的代码世界1 天前
VLC-Qt深度解析:Qt应用中的专业视频播放方案
开发语言·qt
rrr21 天前
【前端开发】|GUI 基本概念和框架基础
前端·qt
Z文的博客1 天前
【避坑实录】Qt 4.8.6 + Paho MQTT C客户端 + OpenSSL静态链接的血泪史
c语言·开发语言·qt·嵌入式linux
(Charon)1 天前
【C++/Qt】Qt 实现 TCP Client:从功能构思到消息收发与日志保存
qt·网络协议·tcp/ip