Go Memory Model: https://golang.org/ref/mem
Happens Before
Hanpens Before,为了深入研究同步问题而提出的概念:
- 关于一个变量 v 的读语句 
r与写语句w,r可以得到w的值需要满足以下条件:rdoes not happene beforew;- There is not other 
w'that happens beforerand afterw; 
 - 一个读语句 
v能够准确地捕获到某个特定的w语句的值,需要满足以下条件:whappends beforer;- Any other 
w'to v either hanppends beforewor afterr; 
 
Golang Lifetime
Initialization, 一个 golang 程序的初始化:
- 对于库 
p引用库q的情况,p的初始化函数开始在q的初始化函数结束之前; - 在函数 
main.main执行前,所有函数的init函数都应该执行完成了; 
Goroutine destruction:
Goroutine 的销毁不会被保证发生在任何事件之前(not guaranteed to happen before any event)。怎么理解这个
happened before呢?比如下面这个例子:1 2 3 4 5var a string func hello() { go func() { a = "hello" }() print(a) }其中,
a的赋值语句发生在一个单独的 goroutine 中,它之后没有任何同步语句,所以它有可能不会被任何事件使用,激进一点的编译器会直接拒绝编译。
Communication
Golang 中线程同步的方法。
Channel
Example:
 |  | 
这段代码一定会输出 hello world,因为根据上面的理论:
a = "hello world"happends before<- chappends beforef()happends beforeprint(a);
Locks
Example:
 |  | 
上面这段代码一定会输出 hello world,因为根据理论:
a = "hello world"happends before 第一个l.Unlock()happens before 第二个l.Lock()happens beforeprint(a);
Once
Example:
 |  | 
上面这个代码中保证了 setup 这个函数只能被调用一次,并且 print 一定会输出 hello world 函数,这是因为 once.Do 保证了每次调用都会在第一调用结束之后。