【C/C++】多线程读写普通 int 变量的一些问题

多线程读写普通int变量问题

场景:线程A写普通int,线程B读同一个普通int,无锁、无volatile。

前提:int在当前平台是32位,对齐访问。

1、会不会出现"字节撕裂(半写值)"?

  • x86/x64:对齐的32位int,读写是原子的CPU指令,写的时候不会读到一半字节,不会读到一个一半旧一半新的畸形数值。

⚠️ 注意:64位long long在32位系统就不是原子,会出现撕裂;但32位对齐int不会。

但!原子 ≠ 线程安全!这是最容易踩坑的地方。

虽然不会读到破碎值,但依然有两个严重问题:可见性问题 、指令重排序问题。


2、可见性问题(CPU缓存)

每个CPU核心有私有L1/L2缓存。

  1. 线程A(CPU0)修改int,新值先写到CPU0缓存,不一定立刻刷回主内存。
  2. 线程B(CPU1)读变量,读的是CPU1自己缓存里的旧副本。

现象:

A已经把x=100,B可能长期读到旧值x=0,永远看不到新修改。

这就是缓存可见性失效。

3、编译器 / CPU指令重排序

编译器、CPU会为性能打乱指令执行顺序,只要单线程逻辑不变。

示例伪代码:

c 复制代码
int flag = 0;
int data = 0;

//线程A
data = 123;
flag = 1;  //通知线程B数据准备好了

//线程B
if(flag == 1){
    print(data);
}

重排序后,线程A实际执行顺序可能变成:

c 复制代码
flag = 1;
data = 123;

线程B看到flag=1,去读data,读到还没更新的旧值。

普通int没有任何屏障,编译器和CPU都可以重排读写。

4、总结现象(普通int,无volatile无锁)

  1. ✅ 对齐32‑bit int:不会发生值撕裂,不会读到半个更新的乱码数字
  2. ❌ 读线程可能一直读到旧值(缓存可见性)
  3. ❌ 指令重排序,读写顺序被打乱,业务逻辑错乱
  4. ❌ 不能保证读到最新写入的值

很多人误以为:int读写原子就不用锁,这是错误。原子只保证不会读到破碎字节,不保证可见性、不保证顺序。


5、怎么解决

C/C++

  1. volatile int x
    • 阻止编译器优化,但是不能阻止CPU硬件重排序、缓存同步,现代多核下不完全可靠,不推荐用于线程同步。
  2. std::atomic<int> x ✅推荐
    • 硬件原子读写,自带内存屏障,解决可见性+重排序。读x.load(),写x.store()。
  3. 互斥锁mutex保护读写。

Java

  • volatile int x:禁止重排序、保证可见性;32位int读写原子。

补充边界案例

  1. 如果int没有内存对齐 (刻意偏移),哪怕32位int,读写不再是CPU原子操作,就会出现值撕裂,读到一半旧一半新的数值。
  2. 64位long long,32位操作系统,普通读写不是原子,一定会撕裂。

最简记忆

对齐32位int:读写指令原子,但不代表线程安全。原子=不会碎;线程安全=可见+有序。两者不是一回事。

如果你需要,我可以写一小段可复现的C++示例代码,演示"写了但是读不到新值"这个现象。

相关推荐
木井巳9 分钟前
【BFS 解决拓扑排序】课程表
java·算法·leetcode·广度优先·宽度优先·推荐算法·图搜索算法
Crazy________20 分钟前
05Linux内存管理核心原理与运维实战
java·开发语言
Logic10122 分钟前
C语言/数据结构数位DP题解:平滑排列数字统计——区间内相邻位差不超过K的数字个数
c语言·数据结构·动态规划·时间复杂度·数位dp·算法题·前导零处理
Nebula_g22 分钟前
JavaSE拓展:工具类Executors
java·开发语言·后端·spring·基础·javase
扶风ff29 分钟前
练题簿在线免费刷题:会员线下组卷、Word 试卷与成绩导入,课堂检测更方便
java·开发语言·算法·小程序·word
鱼宵29 分钟前
Spring AI 可观测与透明化:traceId 串起全链路,思考过程实时直播给用户
java·人工智能·spring·链路追踪·springai
程序员老陆32 分钟前
C++ 多线程通信方式全景:从共享内存到结构化协调
开发语言·c++
Zwawa42 分钟前
把 AO 接回来:黑线和白底之间到底差了多少
c语言·单片机·嵌入式
Raas10044 分钟前
AI网关能做语义缓存吗?MAI Gateway(魔芋企业级AI网关)实战能力深度解读
java·后端·spring
天空鸟_时光不老1 小时前
13-亮点提炼:把技术说辞翻译成业务价值
java·spring boot·spring·spring cloud·mybatis