问题不是Go编译器优化,而是缺乏同步。对 i 的赋值后面没有任何同步事件,因此不能保证任何其他 goroutine 都会观察到它。事实上,激进的编译器可能会删除整个 i 语句。
Go 内存模型
Go 内存模型指定在一个变量中读取变量的条件可以保证 goroutine 观察到在不同 goroutine 中写入同一变量所产生的值。
要串行化访问,请使用通道操作或其他同步原语(例如在sync 和sync/atomic 包。
如果您必须阅读本文档的其余部分才能了解程序的行为,那么您就太聪明了。别自作聪明。
同步
下面的例子中,对a的赋值后面没有任何同步事件,所以不保证能被观察到由任何其他 goroutine 执行。事实上,激进的编译器可能会删除整个 go 语句。
var a string
func hello() {
go func() { a = "hello" }()
print(a)
}
以下示例演示如何使用sync.Mutex.
package main
import (
"sync"
"time"
)
func main() {
mx := new(sync.Mutex)
i := 1
go func() {
for {
mx.Lock()
i
mx.Unlock()
}
}()
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3