go内存模型

· 579 words · 2 minute read

内存模型的规定 🔗

  go的内存模型规定: 在哪些条件下,一个golang中读取的变量时可以观测到另一个golang对同一变量的新写的值。
  序列化访问可以使用channel, sync package

程序的初始化 init 方法的执行顺序 🔗

image

If a package p imports package q, 
the completion of q's init functions happens before the start of any of p's.

goroutine 🔗

goroutine销毁 没有happen before任何程序里的代码

var a string
func hello() {
  go func() {a = "mike"}
  print(a) // 不确定的值
}

channel通信 🔗

  • 写channel的动作 happen before 从channel的读
  • 关闭channel的动作 happen before 从channel中接收零值
  • 从非缓冲channel接收的动作 happen before 写channel

Locks 🔗

sync.Mutex and sync.RWMutex的unlock happen before lock

Once单例对象, 第一次once.Do(f) happen before 后面无数次调用Do(f)

atmoic 🔗

硬件上规定的内存一致性模型

  • 顺序一致模型(sequential consistency model,SC)
  • 完全存储定序(total store order,TSO)
    • 出现store-load乱序的情况
    • 但是硬件保证:先进入store buffer的指令数据必须先于后面的指令数据写到存储器中。
  • 部分存储定序(part store order,PSO)
    • CPU只保证地址相关指令在store buffer中才会以FIFO的形式进行处理
  • 宽松存储模型(relax memory order,RMO)

reference 🔗

[1]The Go Memory Model, Version of June 6, 2022 [2] Memory Models written by Russ Cox [3] Foundations of the C++ Concurrency Memory Model