0
点赞
收藏
分享

微信扫一扫

Go 内存模型

在一个goroutine中:读和写是按照程序顺序执行的,编译器和处理器只有在不会改变oroutine行为的情况下重新编排读和写的顺序。

在多个goroutine中:不同的goroutine会看到不同的执行顺序。

如下两个goroutine,可能的运行结果为:

0 1,1 0,11 ,那么会不会是0 0 呢??下面我们详细介绍下

Go 内存模型_三级缓存

1.首先我们看下cpu重排

用户写下的程序,先要编译成汇编代码,即各种指令,把CPU为了执行效率,会对程序进行重新编排,这就是所谓的内存重排(MemoryRecording)

用户的程序如下

Go 内存模型_多线程_02


重排后可能为

Go 内存模型_多线程_03

但是,当多个goroutine的时候,另外一个goroutine也做了一件事 x=0,那么用户的程序就可能出现问题,可能连续打印100次0。

2.对 0 0结果的解析

现在CPU为了“抚平”内核、内存、硬盘之间的速度差异,高出了各种策略,例如三级缓存。为了让(2)不必等待(1)的执行“效果”可见之后才能执行,我们可以吧(1)的效果曹村道store buffer

2.1.程序开始

Go 内存模型_多线程_04 

2.2A=1保存到Core1的store buffer中


 Go 内存模型_三级缓存_05

2.3B=1写到store buffer后

先执行(1)和(3),将它们直接写入store buffer,接着执行(2)和(4),奇迹发生了

(2)看了下store buffer,没有发现有B的值,于是从Memory读出了0。

(4)看了下store buffer,没有发现有A的值,于是从Memory读出了0。

最后打印出了00。

Go 内存模型_三级缓存_06

因此,对于多线程的程序,所有的CPU都会提供“锁”机制,我们在写程序的时候一定要使用锁,避免出现问题。

举报

相关推荐

0 条评论