x86上的Go原子是增量运算符吗?

Song Gao :

这是一些背景知识:
我需要在go例程之间共享一个计数器变量,该变量用于诸如漏斗之类的东西。我知道在有效的并发部分中有一个漏斗的示例,但是我需要跟踪的数量可能非常大,而且我觉得使用通道中的元素数量来跟踪它效率很低。因此,我正在考虑在不同的例程之间使用共享变量来跟踪数字。

我知道没有显式配置,所有go例程都会映射到一个线程上。但是,如果我在多核计算机上为该程序分配了多个线程,则增量运算符是原子的吗?它是所有相同的不同的数据类型(int32float32,等)在不同的机器(x86_32x86_64arm)?

更具体地说,如果我counter += 1000在一个例程counter -= 512中另一个例程中同时在两个例程同时在两个线程中运行,该怎么办?我是否需要担心线程安全性?我可以把门锁上counter吗?

斯蒂芬·温伯格(Stephen Weinberg):

不,增量永远不应被认为是原子的。使用原子加法函数或互斥量。

假设:

import "sync/atomic"
var counter = new(int32)

一个goroutine可以做atomic.AddInt32(counter, 1000)而另一个atomic.AddInt32(counter, -512)无需互斥体。

如果您希望使用互斥锁:

import "sync"
var counter int32
var mutex sync.Mutex

func Add(x int32) {
    mutex.Lock()
    defer mutex.Unlock()
    counter += x
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章