atomic 原子操作
C++ 的 std::atomic 在 Go 里是 sync/atomic 包:无锁计数器、无锁标志位、无锁状态机的最优解 一、简述 sync/atomic 提供对内存地址的原子操作:Add(原子加)、Load(原子读)、Store(原子写)、CompareAndSwap(比较并交换)、Swap(交换)。它们作用于 int32 / int64 / uint32 / uint64 / uintptr / unsafe.Pointer 以及 atomic.Value。 和 Mutex 相比,原子操作是免锁(lock-free)的:既不阻塞、也无上下文切换开销,在「高频计数器、状态标志、一次性初始化标志」这类场景下性能明显优于锁。代价是只能保护单变量,且不能声明「一段代码的整齐」。 核心要点:读——Load、写——Store、改——Add / CompareAndSwap。把「多步的读-改-写」用一个 CAS 原子完成,是理解 Go 原子操作的钥匙。C++ 里的 std::atomic<int> 心智模型几乎原样平移,差异只在 API 命名和哪些类型支持。 二、C++ 对照速查表 概念 C++ Go 关键差异 原子整数 std::atomic<int> n{0} var n atomic.Int64(或 var n int64 + atomic.AddInt64) Go 1.19+ 有类型化 atomic.Int64,更顺手 原子加 n.fetch_add(1) atomic.AddInt64(&n, 1) Go 返回新值;AddInt32 / AddUint64 等按类型 原子读 n.load() atomic.LoadInt64(&n) Go 读不写也有可能被优化异常,必须用 Load 原子写 n.store(42) atomic.StoreInt64(&n, 42) Go 生硬但显式;Load/Store 配对使用 比较并交换 n.compare_exchange_strong(expected, desired) atomic.CompareAndSwapInt64(&n, old, new) CAS 失败返回 false,循环重试是惯用法 原子交换 n.exchange(42) atomic.SwapInt64(&n, 42) 有返回:交换前旧值 原子布尔/指针 std::atomic<bool> / std::atomic<T*> atomic.Bool(1.19+)/ atomic.Pointer[T](1.19+) Go 类型化版本避免手写 unsafe.Pointer 任意值原子存取 std::mutex 包 struct atomic.Value(存储任意类型) Value 的 Load 要求「上次存过的类型」 内存顺序 memory_order_relaxed / seq_cst Go 不暴露 memory_order,原子操作只有一种语义 自 Go 1.19 起内存模型正式规定:原子访问之间顺序一致(sequentially consistent) 三、逐主题详解 3.1 计数器:AddInt64 / AddUint64 经典场景——无锁计数器,多 goroutine 并发累加。 ...
豫公网安备41108202000982号