郑州高端定制网站建设wordpress ip 访问
在Go并发编程中,当多个 goroutine 同时读写共享变量时,如果没有妥善同步,就会出现数据竞争(Data Race)。Go 提供了
sync/atomic包,用于实现轻量级的原子操作,避免使用锁所带来的性能开销。
一、什么是原子操作?
原子操作指的是在执行过程中不会被任何其他操作中断的操作。在多线程环境中,原子操作确保某个变量的读、写、加减等操作具有一致性和安全性。
二、常用原子操作函数
Go 的 sync/atomic 包支持以下常用操作,主要用于 int32、int64、uint32、uint64 和 unsafe.Pointer 等类型:
| 函数 | 说明 | 
atomic.LoadInt32(&val) | 原子读取值 | 
atomic.StoreInt32(&val, new) | 原子写入值 | 
atomic.AddInt32(&val, delta) | 原子加法(并返回新值) | 
atomic.CompareAndSwapInt32(&val, old, new) | 原子比较并交换 | 
同理还有 Int64、Uint32、Uint64、Pointer 版本 | 
三、使用示例
示例:并发计数器
package mainimport ("fmt""sync""sync/atomic"
)func main() {var counter int32 = 0var wg sync.WaitGroupfor i := 0; i < 1000; i++ {wg.Add(1)go func() {defer wg.Done()atomic.AddInt32(&counter, 1)}()}wg.Wait()fmt.Println("Final Counter:", counter) // 输出应该为 1000
} 
这个例子中我们使用 atomic.AddInt32 来确保并发写入是安全的,避免了 race condition。
四、CompareAndSwap:原子级条件更新
CompareAndSwap 是一个非常强大的函数,可用于实现无锁状态切换。
var status int32 = 0// 尝试将状态从 0 改为 1
if atomic.CompareAndSwapInt32(&status, 0, 1) {fmt.Println("切换状态成功")
} else {fmt.Println("状态已被修改")
} 
如果当前值等于期望值,就会被新值替换;否则不做任何操作,适用于状态机、CAS 重试等场景。
五、原子 vs 锁
| 方面 | 原子操作(atomic) | 锁(Mutex/RWMutex) | 
| 性能 | 极高(CPU级指令) | 较低(涉及调度、抢占) | 
| 适用场景 | 简单计数、状态标记 | 复杂结构同步 | 
| 编程复杂度 | 较高,易出错 | 较低,语义清晰 | 
| 死锁风险 | 无 | 存在风险 | 
六、使用注意事项
- • 原子操作仅适用于简单变量的并发读写,如计数器、标志位。
 - • 不能对结构体、map、slice 等复杂类型直接使用。
 - • 原子操作不能和普通操作混用,否则仍可能产生竞态条件。
 - • 如需读写多个变量或复合结构,推荐使用 
sync.Mutex。 
七、小结
- • 
sync/atomic提供了高性能的原子操作,是无锁并发的核心工具。 - • 适合用于计数器、自旋锁、状态标识等场景。
 - • 不适合管理复杂共享数据,不能代替所有同步手段。
 
