Son*_*Gao 16 concurrency atomic thread-safety go
这里有一些背景知识:
我需要在go例程之间共享一个计数器变量,用于类似漏桶的东西.我知道在Effective Go,并发部分中有一个漏桶的例子,但是我需要跟踪的数量可能非常大,我觉得使用频道中的元素数来跟踪它是低效的.所以我正在考虑在不同的例程之间使用共享变量来跟踪数字.
据我所知,没有显式配置,所有go例程都映射到一个线程.但是,如果我在多核计算机上为程序分配多个线程,那么增量运算符是原子的吗?它是针对不同的数据类型(都是一样的int32,float32等等)在不同的机器(x86_32,x86_64,arm)?
更具体的说,如果我counter += 1000在一个例程中,counter -= 512在另一个例程中,并且这两个例程恰好在两个线程中运行,该怎么办?我需要担心线程安全吗?我要把枪锁上counter吗?
Ste*_*erg 21
不,增量永远不应该被认为是原子的.使用原子加法函数或互斥锁.
让我们假设:
import "sync/atomic"
var counter = new(int32)
Run Code Online (Sandbox Code Playgroud)
一个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
}
Run Code Online (Sandbox Code Playgroud)