var x int done := false go func() { x = f(…); done = true } while done == false { }
这是Go代码。我的恶魔告诉我,这是UB代码。为什么?
Go Memory Model不保证该main程序将始终遵守在goroutine中写入x的值。go常规销毁 部分中提供了一个类似的错误程序作为示例。 在本节中,Go内存模型还专门调出了没有同步的繁忙等待,这是不正确的习惯用法。
main
(在您的情况下,无法保证程序done会遵守在goroutine中写入的值main)
done
在这里,您需要在goroutine中进行某种同步,以确保在in done=true中的for循环迭代之前发生main。
done=true
for
“ while”(Go中不存在)应替换为例如您阻塞的通道(等待通信)
while
for { <-c // 2 }
基于在goroutine中在中c := make(chan bool)创建main并关闭(close(c))的通道()。
c := make(chan bool)
close(c)
的同步包提供其他手段离开主之前等待一个gorountine到端。
例如查看Golang示例等待所有后台goroutine完成:
var w sync.WaitGroup w.Add(1) go func() { // do something w.Done() } w.Wait()