go例程中可能的内存重新排序?

oo7oh9g9  于 2022-12-20  发布在  Go
关注(0)|答案(1)|浏览(126)

go程序:

package main

import (
    "fmt"
    "runtime"
    "time"
)

func main() {
    var x int
    threads := runtime.GOMAXPROCS(0) // get max cpus,
    for i := 0; i < threads; i++ {
        go func() {
            for {
                x++
            }
        }()
    }
    time.Sleep(time.Millisecond * 100)
    fmt.Printf("threads = %v, x = %v\n", threads, x)
}

在我的计算机(Linux)上,打印的结果是:
线程数= 8,x = 0

问题是:

  • 为什么x0,这是cpu缓存中的某种内存重新排序吗?
  • 编译器/ os(Linux)/ cpu对程序做了什么样的优化?
2ledvvac

2ledvvac1#

x之所以是0,是因为存在内存竞争,因为一个共享变量会被至少一个以上的goroutine并发读取,而没有显式同步,所以不能保证从变量读取的数据会看到对它执行的写操作。
很难说我们做了什么样的优化,一种可能性是编译器没有假设x为0,因为它在goroutine中没有被修改,还有很多其他的可能性。

相关问题