go - 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
。有人可以解释为什么吗?也许实际上遍历代码并指出我所缺少的。我真的很感激。
解决方案
推荐阅读
- r - 如何撤销 CRAN 上现有的 R 包
- security - 如何阅读完全由标点符号组成的代码?
- java - 我们可以在自定义 Thread 类中自动装配类实例吗?
- javascript - 为什么 javascript on change 功能无法识别 javascript 生成的输入?
- react-native - 如何在 iOS 和 Android 中检查 react-native 应用程序的大小
- mysql - MySQL SUM 与 SELECT
- multithreading - 数组同步和多线程
- sql - Postgres LEFT JOIN 不返回空值?
- ruby-on-rails - 在carrierwave中为default_url图像分配一个版本
- php - 如何解决 Instagram mgp25 API 中所需的挑战?