🔂sync/atomic包

type
status
date
slug
summary
tags
category
icon
password
Blocked by
Blocking
AI summary
 
 

是什么

  • 在 Go 语言中,sync/atomic 包提供了底层的原子操作,用于对整数类型和指针类型进行原子性的读写和修改
  • 原子操作是不可分割的操作,确保多个 goroutine 并发访问共享数据时,操作不会被中断
CPU指令级别的支持
现代CPU架构提供了一组专门的指令,用于支持原子操作。这些指令能够在单个CPU周期内完成对某些内存操作的读取-修改-写入,这使得这些操作不可分割。也就是说,一旦CPU开始执行这个操作,它会确保整个操作在完成之前不会被其他操作中断。
例如,典型的原子操作指令包括:
  • CMPXCHG(Compare-and-Swap,比较并交换):比较一个内存位置的值和一个给定的值,如果相等,则将其更改为新值。
  • XADD(Exchange and Add,交换并加):将一个数加到一个内存位置的值中,同时返回原来的值。
由于这些操作是在硬件层面直接实现的,它们在执行时能够确保操作的原子性,不需要使用锁来防止数据竞争。

常用函数

sync/atomic 包提供了一系列针对不同数据类型的原子操作函数。下面列出了一些常用的函数:
  • 整数操作
    • atomic.AddInt64(&addr, delta int64) int64:对 int64 类型的值执行加法操作,返回新值。
    • atomic.LoadInt64(&addr) int64:原子地加载 int64 类型的值。
    • atomic.StoreInt64(&addr, val int64):原子地存储 int64 类型的值。
    • atomic.SwapInt64(&addr, new int64) int64:原子地交换 int64 类型的值,返回旧值。
    • atomic.CompareAndSwapInt64(&addr, old, new int64) bool:同上,但用于 int64
  • 指针操作
    • atomic.LoadPointer(&addr) unsafe.Pointer:原子地加载指针值。
    • atomic.StorePointer(&addr, val unsafe.Pointer):原子地存储指针值。
    • atomic.SwapPointer(&addr, new unsafe.Pointer) unsafe.Pointer:原子地交换指针值,返回旧值。
    • atomic.CompareAndSwapPointer(&addr, old, new unsafe.Pointer) bool:原子地比较并交换指针值。
  • 布尔值操作
    • Go 并没有专门的 atomic 布尔操作函数,但可以通过整数操作来模拟布尔值操作。例如,使用 atomic.StoreInt3201 分别表示 falsetrue
 
 

使用场景

轻量级的锁-自旋锁

在竞争不频繁或者上下文切换比较的场景下,使用自旋锁,可以减少互斥锁带来的协程阻塞和上下文切换
 

并发场景下的标识符

使用 atomic 可以避免使用锁
 
 

指针交换

 

实现并发场景下的计数

 
 
 
Prev
内存对齐
Next
go中常见的内存泄露场景
Loading...
Article List