package main
import (
"fmt"
"sync"
)
var ex, ey int
func main() {
var ex, ey int
var ewg sync.WaitGroup
ewg.Add(2)
go func() {
ex = 1
fmt.Println("ey = ", ey)
ewg.Done()
}()
go func() {
ey = 1
fmt.Println("ex = ", ex)
ewg.Done()
}()
ewg.Wait()
}
这一段代码
打印的结果又很多种
ey = 0 ex = 1
ex = 0 ey = 1
ex = 1 ey = 1
ey = 1 ex = 1
但是还有一种结果是: ex = 0 ey = 0,虽然你执行的时候可能不会出现这种情况,但是他确实是存在的
出现这种结果的可能有两个原因:
一,因为赋值和打印的变量不是同一个,所以编译器就可能会认为两条语句的执行顺序不会影响结果,然后就交换了这两个语句的执行顺序
二,两个协程可能在不同的CPU上运行,假设第一个协程在CPU1上运行,第二个协程在CPU2上运行,但是由于每个CPU都会缓存,只有在必要的时候才会写入主内存,其他的CPU才能看到。
CPU1对 ex 进行了修改,但是它只是在自己的本地缓存进行了修改,并没有写入到主内存,所以CPU2看不到,它就打印它上次从主内存取得的过期值。同理CPU1也是打印了 ey 的过期值。所以就会出现 ex和ey同时等于零的情况