Go语言中的原子操作是一种在并发编程中用于对共享数据进行原子性访问和修改的机制。原子操作可以确保对共享数据的操作在不被中断的情况下完成,要么完全执行成功,要么完全不执行,从而避免了竞态条件和数据竞争问题。Go语言通过sync/atomic
包提供了对原子操作的支持,主要包括以下几类:
1. 增减操作(Add)
增减操作用于对一个整数型的变量进行原子的增减。sync/atomic
包提供了一系列以Add
开头的函数,包括AddInt32
、AddInt64
、AddUint32
、AddUint64
和AddUintptr
等。这些函数接收一个指向变量地址的指针和一个要增减的值作为参数,并返回变量增减后的新值。
2. 载入操作(Load)
载入操作用于原子地读取一个变量的值。sync/atomic
包提供了一系列以Load
开头的函数,包括LoadInt32
、LoadInt64
、LoadUint32
、LoadUint64
、LoadUintptr
和LoadPointer
等。这些函数接收一个指向变量地址的指针作为参数,并返回变量的当前值。
3. 存储操作(Store)
存储操作用于原子地将一个新值存储到一个变量中。sync/atomic
包提供了一系列以Store
开头的函数,包括StoreInt32
、StoreInt64
、StoreUint32
、StoreUint64
、StoreUintptr
和StorePointer
等。这些函数接收一个指向变量地址的指针和一个要存储的新值作为参数。
4. 比较并交换操作(CompareAndSwap)
比较并交换操作(CAS)用于在变量的当前值等于一个预期值时,将其更新为一个新值。sync/atomic
包提供了一系列以CompareAndSwap
开头的函数,包括CompareAndSwapInt32
、CompareAndSwapInt64
、CompareAndSwapUint32
、CompareAndSwapUint64
、CompareAndSwapUintptr
和CompareAndSwapPointer
等。这些函数接收一个指向变量地址的指针、变量的预期旧值和新值作为参数,如果变量的当前值等于预期旧值,则将其更新为新值,并返回true
;否则,不做任何修改,并返回false
。
5. 交换操作(Swap)
交换操作用于将一个变量的值原子地设置为一个新值,并返回变量的旧值。sync/atomic
包提供了一系列以Swap
开头的函数,包括SwapInt32
、SwapInt64
、SwapUint32
、SwapUint64
、SwapUintptr
和SwapPointer
等。这些函数接收一个指向变量地址的指针和一个要设置的新值作为参数。
需要注意的是,所有原子操作方法的被操作数形参必须是指针类型,通过指针变量可以获取被操作数在内存中的地址,从而施加特殊的CPU指令,确保同一时间只有一个goroutine能够进行操作。
总的来说,Go语言的原子操作提供了一种高效、简洁且可靠的并发控制机制,能够在并发编程中确保共享数据的一致性和正确性。