var x int
done := false
go func() { x = f(...); done = true }
while done == false { }
这是Go代码段。我的朋友告诉我这是UB代码。为什么呢?
答案 0 :(得分:3)
如“Why does this program terminate on my system but not on playground?”
中所述Go Memory Model不保证
main
程序可以观察到goroutine中写入x的值。
在go routine destruction部分中给出了一个类似的错误程序作为示例 Go Memory Model还专门调用了忙碌等待而没有同步作为本节中不正确的习惯用法。
(在您的情况下,无法保证done
程序将会在goroutine中写入main
的值
在这里,你需要在goroutine中进行某种同步,以保证在done=true
中for
循环的一次迭代之前发生main
。
“while
”(Go中不存在)应该替换为您阻止的频道(等待通信)
for {
<-c // 2
}
基于在c := make(chan bool)
中创建并在goroutine中关闭(main
)的频道(close(c)
)。
sync package提供了其他方法来等待gorountine在退出main之前结束。
例如参见Golang示例Wait until all the background goroutine finish:
var w sync.WaitGroup
w.Add(1)
go func() {
// do something
w.Done()
}
w.Wait()