一尘不染

为什么此代码未定义行为?

go

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

这是Go代码。我的恶魔告诉我,这是UB代码。为什么?


阅读 316

收藏
2020-07-02

共1个答案

一尘不染

Go Memory
Model不保证该main程序将始终遵守在goroutine中写入x的值。go常规销毁
部分中提供了一个类似的错误程序作为示例。
在本节中,Go内存模型还专门调出了没有同步的繁忙等待,这是不正确的习惯用法。

(在您的情况下,无法保证程序done会遵守在goroutine中写入的值main

在这里,您需要在goroutine中进行某种同步,以确保在in done=true中的for循环迭代之前发生main

while”(Go中不存在)应替换为例如您阻塞的通道(等待通信)

for {
    <-c // 2
}

基于在goroutine中在中c := make(chan bool)创建main并关闭(close(c))的通道()。


同步包提供其他手段离开主之前等待一个gorountine到端。

例如查看Golang示例等待所有后台goroutine完成

var w sync.WaitGroup
w.Add(1)
go func() {
    // do something
    w.Done()
}
w.Wait()
2020-07-02