Files
Operating-System/Thread/atom_operation.md
2026-03-22 17:40:44 +08:00

3.0 KiB
Raw Permalink Blame History

你的理解已经非常接近核心了,但如果从底层并发编程的角度来看,“不可中断”和“最小”这两个词需要更精确的定义。

在计算机科学中,**原子操作Atomic Operation**的重点确实有两个,但通常表述为:不可分割性Indivisibility可见性Visibility


1. 重点一不可分割性Indivisibility—— 你说的“最小”

“原子”一词源于希腊语 atomos,意为“不可切分”。

  • 含义:一个操作要么全部执行成功,要么完全不执行。在执行过程中,绝不会停在中间某个状态。
  • 为什么不是单纯的“最小”?:有些原子操作在底层可能包含多个微指令(例如 CAS 操作),但 CPU 保证这些指令在逻辑上是一个整体。
  • 现象:对于其他线程来说,它们永远观察不到这个操作的“中间结果”。

2. 重点二:排他性/原子性Atomicity—— 你说的“不可中断”

这里需要区分**“软件中断”“硬件并发访问”**。

  • 非原子操作的危机:比如 i++。它在 CPU 层面分为三步:
    1. 从内存读 i 到寄存器。
    2. 寄存器加 1。
    3. 写回内存。 如果你在第 2 步执行完,还没来得及写回内存时,线程被中断(上下文切换)了,另一个线程进来读到了旧的值,就会导致数据错乱。
  • 原子操作的保证:原子操作通过硬件锁(如总线锁或缓存锁)保证,在操作完成之前,没有任何其他核心或线程能干预这块内存

3. 一个常被忽略的重点内存顺序Memory Ordering

除了你提到的两点,现代高级编程(尤其是你熟悉的 C++20Rust)中,原子操作还有一个至关重要的属性:同步与可见性

  • 可见性:当线程 A 完成一个原子写操作,线程 B 必须能立即“看到”这个修改。
  • 防止重排序:编译器和 CPU 为了优化性能,经常会乱序执行指令。原子操作(配合内存序 std::memory_order)能像一道屏障一样,告诉 CPU“不要把我前后的指令乱跳”确保逻辑顺序正确。

总结:你的理解对吗?

  • “最小”:对。它是逻辑上的最小单位,不可再分。
  • “不可中断”:对。它保证了操作的连贯性,不会被线程切换或竞争对手打断。

底层小知识: 在 x86 架构下,普通的对齐内存地址的 mov(赋值)指令本身就是原子的。但像 add 这种复合操作,必须加上 LOCK 前缀指令,才能变成真正的“原子操作”。


既然你之前研究过 E2hangJson 的开发,在处理多线程解析或者全局引用计数时,你应该接触过 std::atomic

想看看在 C++ 中,一个简单的 i++ 是如何通过汇编指令变成加锁的原子操作的吗?我们可以对比一下 LOCK 前缀的效果。