首页 > 解决方案 > goroutine 共享变量展示

问题描述

我有以下一段Go代码

package main

import (
    "fmt"
    "time"
)


func f(name string, x *int) {
    for i := 0; i < 5; i++ {
        *x++
        fmt.Printf("%s: %d\n", name, *x)
    }
}

func main() {
    var x int
    go f("routine 1", &x)
    go f("routine 2", &x)
    time.Sleep(1 * time.Second)
}

此代码生成的输出如下所示:

routine 1: 1
routine 1: 3
routine 2: 2
routine 2: 5
routine 2: 6
routine 2: 7
routine 2: 8
routine 1: 4
routine 1: 9
routine 1: 10

我对以下内容感到困惑:

routine 1: 1
routine 1: 3
routine 2: 2

具体来说routine 2: 2。在我看来应该是routine 2: 3。这就是我这么认为的原因。

首先例程 1 执行,将 x 增加 1 并显示它(x = 1)。这就是我们看到的原因routine 1: 1。然后例程 2 执行并将 x 增加 1 (x = 2),但是在显示它之前Go调度程序将其停止并切换回例程 1。例程 1 将 x 增加 1 (x = 3) 并显示它,这就是为什么我们要看到routine 1: 3。然后Go调度程序切换回例程 2。此时例程 2 正在显示 x ,它应该等于 3 但是我们看到显示的是routine 2: 2。有人可以解释发生了什么吗?我觉得我错过了一些非常重要的东西,但我不知道它是什么。

编辑 让我澄清一下我故意创造了一个竞争条件。我只是想看看发生了什么。但是我无法解释为什么会这样。在我看来,我应该看到,routine: 2: 3但我看到了routine 2: 2。有人可以解释为什么吗?也许实际上遍历代码并指出我所缺少的。我真的很感激。

标签: gogoroutine

解决方案


在 Golang 中并发代码执行顺序是可预测的。您可能希望使用互斥锁通道来处理来自 goroutine 的共享变量。


推荐阅读