进行整数数据竞争

hid*_*atz -1 concurrency go goroutine

关于 int 类型上 Go 数据竞争的问题。当我运行下面的程序时go run -race main.go

package main

import "fmt"

var i int

func main() {

    go func() {
        i = 10
    }()

    i = 5

    fmt.Println(i)
}
Run Code Online (Sandbox Code Playgroud)

它显示数据竞争警告。

~  $ go run -race main.go
5
==================
WARNING: DATA RACE
Write at 0x000000605908 by goroutine 7:
  main.main.func1()
      /home/dty1er/main.go:80 +0x3a

Previous write at 0x000000605908 by main goroutine:
  main.main()
      /home/dty1er/main.go:83 +0x56

Goroutine 7 (running) created at:
  main.main()
      /home/dty1er/main.go:79 +0x46
==================
Found 1 data race(s)
exit status 66
Run Code Online (Sandbox Code Playgroud)

我知道为什么会发生这种数据竞争;var i由 2 个 goroutine 同时访问,无需任何同步。我不明白的是这段代码的实际问题。根据我的理解,因为iint(我的电脑是64位),所以i实际上是64位。在 64 位机器上,i可以原子地读/写。所以我认为不存在实际问题。

例如,如果类型是map或slice,由于CPU对内存的访问不能是原子的,所以它的中间状态有时是可见的,这是有问题的。

但是当我只使用 int 类型值时,即使存在数据竞争,看起来也没有实际问题。

我的理解正确吗?

Vol*_*ker 5

我的理解正确吗?

不,不是。具有数据竞争的程序是未定义的,并且使用 int 并不会神奇地使这种数据竞争消失。编译器和硬件不再像 80 年代那样简单。数据竞争是一个主要错误。

您可以使用sync/atomic以无竞争的方式处理整数,但在此设置中简单的 int 是完全错误的。