Golang的调度模型

Golang中的内存模型

The Go memory model specifies the conditions under which reads of a variable in one goroutine can be guaranteed to observe values produced by writes to the same variable in a different goroutine.

  • 翻译过来就是说,Go内存模型通过定义以下的条件,来保证在一个goroutine可以观察到另外的goroutine对这个相同变量的写操作。

Happens Before

在一个goroutine中,读和写的顺序一定是安装程序中的顺序执行的。编译器和处理器只有在不会在改变这个goroutine的行为的时候,才可能修改读和写的执行顺序。

但是由于重排,不同的gouroutine会看到不同的执行顺序。

例如,一个goroutine执行a = 1;b = 2;,另一个goroutine可能看到b在a之前更新。

为了说明读和写的必要性,go引入了Happens Before原语,来对内存模型中指定的条件进行描述。Happens Before翻译过来就是先行发生的意思。

Happens Before的定义:

  • 如果事件e1发生在事件e2之前,那么我们说e2发生在事件e1之后。同样,如果e1不发生在e2之前,也不发生在e2之后,那么我们说e1和e2同时发生。

内存模型指定了哪些条件

go的Happens Before定义了2组条件:

第一组条件:

当上面2个条件都满足的时候,对变量v的读操作r是允许对v的写入操作w进行监测的

  • r不先行发生于w
  • 在w后r前没有对v的其他写操作
第二组条件:

为了确保对变量v的读取操作r能够监测到特定的对v的写操作w, 需要确保w是r允许看到的唯一写操作。即当下面条件满足时,则r能保证监测到w

  • w先行发生于r
  • 对共享变量v的其它任何写入操作都只能发生在w之前或r之后

在单个goroutine中,这2组条件的定义是一样的。但是,如果在多goroutine的环境下,第二组条件要求会更严格,因为它需要确保没有其他的写入操作与w或者r同时发生

我们看第一组条件,为什么说它没有第二组条件这么严格,r不先行发生于w,并不意味着,r就在w之后,因为它们可以是同时发生。

因此,需要特别注意的是,第一组条件的说法,在2个并发的goroutine来说,一个goroutine能否读到另一个goroutine中写入的数据是不确定的,可能可读到,可能读不到。

第二组条件,由于r发生在w之后,对共享变量v的其它任何写入操作都只能发生在w之前或r之后,意思就是说在r到w这一段期间之间,没有其他的写操作w’,也没有和r并行的写操作w’'发生,所以我们可以说,r读到的值必然是w写入的值。

下面这个图是从go编译语言网站扣过来的:

单Go程的情形:
-- w0 ---- r1 -- w1 ---- w2 ----  r2 ---- r3 ------>

这里不仅是个偏序关系,还是一个良序关系:所有 r/w 的先后顺序都是可比较的。

双Go程的情形:
-- w0 -- r1 -- r2 ---- w3 ----  w4 ---- r5 -------->
-- w1 ----- w2 -- r3 ----  r4 ---- w5 -------->

单Go程上的事件都有先后顺序;而对于两条Go程,情况又有所不同。即便在时间上 r
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值