
Golang中如何编写无锁(Lock-Free)的数据递增函数
时间:2026-07-02
### 聊到 Go 的并发编程,`atomic.AddInt64` 绝对算得上是个高频选手。
它在 Go 标准库中的地位,基本上等同于"无锁递增"的标准答案。直接调用 CPU 的 `XADD`(x86)或 `LDADD`(ARM)等硬件原语,不经过操作系统的互斥量,也不会触发 goroutine 阻塞——性能损耗极低。
但实际用起来,容易栽的几个坑得先说清楚。
**第一,它必须接收一个 `int64` 类型的指针**,不能直接对普通变量或 `int` 类型操作。Go 的 `int` 宽度跟平台有关,而 `atomic` 包不提供 `atomic.AddInt` 这样的函数,所以计数器用 `int64` 是最稳当的。
**第二,确保目标变量的生命周期足够长**。全局变量、结构体字段、或者通过 `new(int64)` 分配出来的内存都没问题,但别对局部变量的指针进行操作——生命周期问题比想象中来得更频繁。
**第三,别试图用 `++` 或 `+=` 替代 `atomic.AddInt64`**。这些操作不是原子的,即便变量是指针传递的,在多 goroutine 并发读写下照样会出现竞态。跑一下 `go run -race`,马上就能看到 `race detected` 的恐慌提示。
```go
var counter int64
// 正确:每次 +1
atomic.AddInt64(&counter, 1)
// 错误:非原子操作
counter++ // ⚠️ 竞态风险
```
本文转载于:https://www.php.cn/faq/2755414.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。