You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

x86平台非对齐int64_t访问:并发读写线程会读取中间状态值吗?

x86架构下非对齐int64_t的线程读写行为分析

核心问题解答

1. 非对齐int64_t写入是否会触发两次内存访问?

是的。Intel x86(包括x86_64)架构硬件支持非对齐内存访问,但对于跨对齐边界的64位非对齐访问(比如你提到的地址0x7ffbc82f1c7a,低3位为0b010,意味着这个int64_t会跨越两个8字节对齐块),CPU会将单次64位读写拆分为两个独立的内存事务:分别访问两个对齐的内存块,再在内部合并数据。

2. 读取线程是否可能读到中间状态?

完全可能,这正是你遇到的情况。由于非对齐写入被拆分为两次独立操作,两次操作之间存在时间窗口:如果读取线程在第一次写入完成、第二次写入未完成时读取该变量,就会得到一个混合了旧值和新值的中间状态。

结合你的案例分析

三者的补码对比:

The two's complement of -1 is: 
1111111111111111111111111111111111111111111111111111111111111111
The two's complement of 153538 is: 
0000000000000000000000000000000000000000000000100101011111000010
The two's complement of -281474976557118 is: 
1111111111111111000000000000000000000000000000100101011111000010

你观察到的数值变化完全符合非对齐访问的特性:

  • 原数值-1的补码是全64位1
  • 目标数值153538的补码是高48位为0,低16位为有效数据
  • 读取到的中间值补码是高16位保留旧值的全1,低48位已更新为目标值的对应部分

这是因为你的非对齐int64_t跨越了两个8字节对齐块:第一个块的前2字节属于旧值(未被修改),而剩余的6字节以及第二个块的2字节已经被更新为目标值,读取时正好捕获到这个中间状态。

结论

这种行为在Intel x86 CPU上是完全符合预期的。需要明确:x86架构仅保证对齐的64位内存访问是原子操作(不会被拆分为多个内存事务,读写过程中不会出现中间状态);非对齐的64位访问不具备原子性,多线程场景下必然存在读到中间状态的风险。

内容的提问来源于stack exchange,提问作者world hello

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 08:03:10