mutex加锁是否保证内存同步?goroutine修改变量后其他goroutine能否立刻读取
Go Mutex 内存可见性问题解答
结论先行
不能保证goroutine B立刻读取到n修改后的值,Go mutex的内存同步保证是有前置条件的,你当前的写法不符合要求。
具体原理
根据Go官方内存模型的规范:
- 针对同一个互斥锁
mu的Unlock()调用,happen before 任意后续对同一个mu的Lock()调用的返回。
这也就意味着,mutex的内存同步保证只作用在成对使用Lock/Unlock的 goroutine 之间:
- 你在goroutine A里先
Lock()修改n再Unlock(),所有对n的修改,只会对后续先调用mu.Lock()再读取n的goroutine可见 - 你现在goroutine B里直接无锁读取n,属于典型的并发数据竞争,是Go明确的未定义行为:可能读到旧值,可能读到新值,甚至在部分架构下可能出现读取到异常中间值的情况。
正确写法
如果要保证goroutine B能读到goroutine A修改后的n值,读取端也要加相同的互斥锁:
// goroutine B 代码 mu.Lock() fmt.Println(n) mu.Unlock()
只要goroutine A的Unlock()已经执行完成,上面的写法就一定能读到n的最新值。
内容的提问来源于stack exchange,提问作者space
相关产品推荐
相关产品推荐

