”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 为什么我的 Goroutine 递增变量会产生意外的结果?

为什么我的 Goroutine 递增变量会产生意外的结果?

发布于2024-11-05
浏览:747

Why Does My Goroutine Incrementing a Variable Produce Unexpected Results?

这是编译器优化的结果吗?

在此代码片段中,启动了一个 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