Go语言中什么操作叫做原子操作

发布于 1周前 作者 caililin 最后一次编辑是 5天前 来自 问答

Go语言中什么操作叫做原子操作

原子操作即是进行过程中不能被中断的操作,针对某个值的原子操作在被进行 的过程中,CPU 绝不会再去进行其他的针对该值的操作。为了实现这样的严谨性,原子操作仅会由一个独立的 CPU 指令代表和完成。原子操作是无锁的,常常直接通过 CPU 指令直接实现。 事实上,其它同步技术的实现常常依赖于原 子操作。

1 回复

在Go语言中,原子操作指的是在执行过程中不会被线程(在Go中称为goroutine)调度机制打断的操作,这类操作在多线程环境中是安全的,无需使用互斥锁(mutexes)或其他同步机制即可保证数据的一致性和完整性。Go的sync/atomic包提供了这类操作的实现。

原子操作通常用于对共享变量的简单操作,如自增、自减、加载(读取)、存储(写入)等,这些操作在执行时是原子的,即它们要么完全执行,要么完全不执行,不会出现只执行了一半的情况。

示例:使用sync/atomic包进行原子操作

以下是一个使用sync/atomic包中的AddInt32函数对int32类型变量进行原子自增操作的示例:

package main

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

func main() {
    var counter int32

    var wg sync.WaitGroup
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            // 对counter进行原子自增操作
            atomic.AddInt32(&counter, 1)
        }()
    }

    wg.Wait() // 等待所有goroutine执行完毕

    // 安全地读取counter的值
    fmt.Println(counter) // 输出结果可能为10,但根据调度情况可能有所不同(理论上应该是10,因为每个goroutine都对其进行了+1操作)
}

注意:虽然上面的代码示例中每个goroutine都对counter进行了+1操作,且使用了atomic.AddInt32来确保操作的原子性,但由于fmt.Println(counter)的调用不是原子的,且可能受到Go运行时调度的影响,所以在并发极高的情况下,最终打印的结果可能并不总是严格等于启动的goroutine数量(在这个例子中是10)。然而,atomic.AddInt32的使用确保了每次+1操作的原子性,这是处理并发时保证数据一致性的关键。

在实际应用中,当你需要跨多个goroutine安全地更新或读取共享变量时,应该考虑使用sync/atomic包提供的原子操作。

回到顶部