在此代码片段中,启动了一个 goroutine 并重复递增变量 i:
package main
import "time"
func main() {
i := 1
go func() {
for {
i
}
}()
然而,输出始终为1。这种行为可以归因于Go内存模型和这段代码的具体实现。
Go内存模型
The Go 内存模型定义了在一个 Goroutine 中读取变量时可以保证观察到在不同 Goroutine 中写入同一变量所产生的值的条件。它强调了同步对于并发访问共享数据的重要性。
省略同步
在给定的代码中:
- 对 i 的赋值(即 i )后面没有任何同步事件,表明更改可能不会立即对其他 goroutine 可见。
- 编译器可以通过将其简化为无操作来优化此循环优化。
编译器优化
激进的编译器可能会删除 i 语句,从而有效地将 goroutine 缩减为:
for {}
同步示例
为了证明问题源于缺乏同步,请考虑以下代码:
package main
import (
"sync"
"time"
)
func main() {
mx := new(sync.Mutex)
i := 1
go func() {
for {
mx.Lock()
i
mx.Unlock()
}
}()
在这种情况下,输出不再是 1,而是一个很大的数字,正如预期的那样。 sync.Mutex 提供同步并确保两个 goroutine 以受控方式访问 i,允许 goroutine 递增 i 并使更改对主例程可见。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3