golang 协程读写上下文变量 一直为 0

2021-03-20 15:28:26 +08:00
 xuletter2021

如代码 1:运行过程中无论 sleep 多久,输出都是 0

func main() {
	var x int
	go func() {
		for {
			x++
		}
	}()
	time.Sleep(time.Duration(10) * time.Second)
	fmt.Println("**************")
	fmt.Println(x)
	fmt.Println("**************")
}

如代码 2:在上面第六行加了点代码就输出就变了,一直不明白为什么

func main() {
	var x int
	go func() {
		for {
			x++
			// select()
			// or
			// fmt.Println("ddd")
		}
	}()
	time.Sleep(time.Duration(1) * time.Second)
	fmt.Println("**************")
	fmt.Println(x)
	fmt.Println("**************")
}

求大佬指点

2914 次点击
所在节点    Go 编程语言
24 条回复
lysS
2021-03-20 19:56:46 +08:00
被优化了(伊,怎么感觉乖乖的)
你把 // fmt.Println("ddd")的注释取消有可以了
lewinlan
2021-03-20 20:06:58 +08:00
楼上说的缓存问题的确值得学习,但应该不是这个问题的原因,10 秒怎么得也刷到 L3 了才对。
看了下汇编,优化成了空循环了,所以应该是优化的问题。
xfriday
2021-03-20 22:46:32 +08:00
这个问题我之前在 github 上提过 issue,go 的编译器会把这种情况下的修改的代码优化掉的,也只有 golang 会这么做,别的语言只是不保证可见性,但最终一定会读取到新值(并非所有场景都需要完全的一致性性),在 golang 里却永远读不到新值。
sikasjc
2021-03-22 11:35:37 +08:00
可以看这里,同样的问题,可以看汇编代码发现区别 https://www.zhihu.com/question/434964023

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/763452

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX