🔂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.StoreInt32
将0
和1
分别表示false
和true
。
使用场景
轻量级的锁-自旋锁
在竞争不频繁或者上下文切换比较
重
的场景下,使用自旋锁
,可以减少互斥锁带来的协程阻塞和上下文切换并发场景下的标识符
使用 atomic 可以避免使用锁
指针交换
实现并发场景下的计数
Prev
内存对齐
Next
go中常见的内存泄露场景
Loading...