Introduction
Go内存模型指定了一系列条件,在该条件下,可以保证在一个goroutine中对某个变量的读取操作可以观察(observe)到其他goroutine对这个变量写入的值。(内存可见性)
Happens-before
指令重排序对goroutine内部的读写顺序可能有影响,但不会影响代码定义的当前goroutine整体的行为。
例如在goroutine1中有代码a = 1; b = 2;
,在其他goroutine中可能观察到b先于a赋值,但对于goroutine1,其行为不会因为指令重排序发生变化。
Go语言中的Happens-Before:Happens-Before定义了内存操作的顺序。如果e1 happens-before e2, 则 e2 一定在e2发生之后才发生。如果e1 e2 没有happens-before的关系限制,则e1 e2是并发发生的。在单个goroutine内部, happens-before 次序就是程序定义的顺序。
读取操作r对变量v 可以观察到写入操作w对变量v的写入,必须同时满足如下两个条件:
- r不能先于w发生
- 没有其他的对变量v的写入操作w‘ 晚于 w 但 先于r发生
读取操作保证能观察到写入操作w对变量v的写入,必须同时满足如下两个条件:
- w 先于 r发生
- 任何其他对变量v的写入操作,要么先于w发生,要么晚于r发生。