问题不是 Go 编译器优化,而是缺乏同步。对 i 的赋值后面没有任何同步事件,因此不能保证任何其他 goroutine 都会观察到它。事实上,激进的编译器可能会删除整个 i 语句。
Go 内存模型
Go 内存模型指定在一个变量中读取变量的条件可以保证 goroutine 观察到在不同 goroutine 中写入同一变量所产生的值。
要序列化访问,请使用通道操作或其他同步原语(例如sync和sync/atomic包中的同步原语)保护数据.
如果您必须阅读本文档的其余部分才能理解程序的行为,那您就太聪明了。别自作聪明。
同步
在下面的示例中,对 a 的赋值后面没有任何同步事件,因此不保证能够被观察到由任何其他 goroutine 执行。事实上,激进的编译器可能会删除整个 go 语句。
<code class="go">var a string func hello() { go func() { a = "hello" }() print(a) }</code>
以下示例演示如何使用sync.Mutex 序列化对 i 的访问。
<code class="go">package main import ( "sync" "time" ) func main() { mx := new(sync.Mutex) i := 1 go func() { for { mx.Lock() i++ mx.Unlock() } }() <-time.After(1 * time.Second) mx.Lock() println(i) mx.Unlock() }</code>
以上是为什么我的 Goroutine 的值对其他人不可见?的详细内容。更多信息请关注PHP中文网其他相关文章!