Go内存模型简单介绍1 | Go主题月

268 阅读2分钟

Go的内存模型介绍

Go内存模型指定了一种条件,在一个goroutine中读取到一个变量对其它goroutine写入这个变量的值会是最新即可见性。

Happens Before

在一个单goroutine中,happens-before 顺序会被程序重排。

1,读取变量v被允许看到写后的值,当两者满足下面条件 image.png 2,当一个线程读取变量v时,保证这个线程能够获取到特定一个线程写入变量v后的值,并且保证这个写操作是唯一允许这个线程可以获取到最新的值,要保证如下两个条件:

image.png

这组条件比第一组条件更加健壮,它需要没有其他写操和以上的读或者写同时发生。

以上条件在单个goroutine上是没有冲突,是有价值的。如果在多个goroutine时,要使用同步机制设置happens-before条件,来保证获取到期望的值。

当初始化变量v为0写入内存时,其数据类型也被写入。

对大于单个机器字符的值的读取和写入,按照未指定的顺序执行多个机器字符大小的操作。

同步

对于go语句开启一个新goroutine发生在这个goroutine执行开始前。 例如,在这个程序:

var a string

func f() {
	print(a)
}

func hello() {
	a = "hello, world"
	go f()
}

在某些情况下调用hello将打印"hello, world"。

Goroutine销毁

goroutine的结束无法保证在这个程序任何事件之前发生。例如,在这个程序:

var a string

func hello() {
	go func() { a = "hello" }()
	print(a)
}

给变量a赋值不遵循审核同步机制,所以a的最新值无法保证可以被任何其他goroutine获取到。实际上,强大的编译器可能会删除掉那个a全局变量语句。

如果一个goroutine对变量修改必须被其他goroutine获取到,可以使用同步方法,比如加锁,通道传输设置一个稳定的执行顺序。