在一个goroutine中:读和写是按照程序顺序执行的,编译器和处理器只有在不会改变oroutine行为的情况下重新编排读和写的顺序。
在多个goroutine中:不同的goroutine会看到不同的执行顺序。
如下两个goroutine,可能的运行结果为:
0 1,1 0,11 ,那么会不会是0 0 呢??下面我们详细介绍下
1.首先我们看下cpu重排
用户写下的程序,先要编译成汇编代码,即各种指令,把CPU为了执行效率,会对程序进行重新编排,这就是所谓的内存重排(MemoryRecording)
用户的程序如下
重排后可能为
但是,当多个goroutine的时候,另外一个goroutine也做了一件事 x=0,那么用户的程序就可能出现问题,可能连续打印100次0。
2.对 0 0结果的解析
现在CPU为了“抚平”内核、内存、硬盘之间的速度差异,高出了各种策略,例如三级缓存。为了让(2)不必等待(1)的执行“效果”可见之后才能执行,我们可以吧(1)的效果曹村道store buffer
2.1.程序开始
2.2A=1保存到Core1的store buffer中
2.3B=1写到store buffer后
先执行(1)和(3),将它们直接写入store buffer,接着执行(2)和(4),奇迹发生了
(2)看了下store buffer,没有发现有B的值,于是从Memory读出了0。
(4)看了下store buffer,没有发现有A的值,于是从Memory读出了0。
最后打印出了00。
因此,对于多线程的程序,所有的CPU都会提供“锁”机制,我们在写程序的时候一定要使用锁,避免出现问题。