为什么这段代码是未定义的行为?

时间:2014-05-13 13:03:28

标签: go

  var x int
  done := false
  go func() { x = f(...); done = true }
  while done == false { }

这是Go代码段。我的朋友告诉我这是UB代码。为什么呢?

1 个答案:

答案 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=truefor循环的一次迭代之前发生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()