Go语言中的原子操作是通过标准库sync/atomic提供的,这些操作能够保证在多个goroutine访问共享资源时的安全性,

即使在没有锁的情况下也能保证操作的原子性。原子操作通常用于低层次的同步场景或者性能敏感的场景,

因为它们避免了锁的开销,可以直接通过硬件提供的原子指令来保证操作的原子性。

sync/atomic包提供了一系列函数,用于执行基本的原子内存操作,主要包括对整数类型的读写以及加法操作,

还有更通用的比较并交换(Compare and Swap,CAS)操作,以及原子地加载(Load)和存储(Store)值。

常见的原子操作函数

AddInt32, AddInt64, AddUint32, AddUint64, AddUintptr: 对指定的值执行原子加法操作。

CompareAndSwapInt32, CompareAndSwapInt64, CompareAndSwapPointer: 如果当前值等于旧值,则将其替换为新值。

LoadInt32, LoadInt64, LoadPointer: 原子地加载指定位置的值。

StoreInt32, StoreInt64, StorePointer: 原子地存储指定的值到指定位置。

SwapInt32, SwapInt64, SwapPointer: 原子地交换指定位置的值。

使用原子操作AddInt64的简单示例,用于原子地增加一个int64类型的计数器:

package main

import (
    "fmt"
    "sync"
    "sync/atomic"
    "time"
)

func main() {
    var counter int64

    const goroutines = 100
    var wg sync.WaitGroup
    wg.Add(goroutines)

    for i := 0; i < goroutines; i++ {
        go func() {
            defer wg.Done()
            for c := 0; c < 1000; c++ {
                atomic.AddInt64(&counter, 1)
            }
        }()
    }

    wg.Wait()
    fmt.Println("Counter:", counter)
}

即使有多个goroutine同时增加计数器的值,使用atomic.AddInt64也能保证每次增加操作的原子性,最终结果是准确无误的。

原子操作非常有用,但它们只适用于简单的数值或指针操作。 在更复杂的同步场景中,可能需要使用互斥锁(sync.Mutex)或其他同步机制。