关于两段使用Go协程的代码的性能问题令人困惑。

huangapple go评论77阅读模式
英文:

Confusing performance about two pieces of code with go goroutines

问题

这是一段代码,打印出的x的值是一个不确定的整数,例如:x = 359931570x = 325604846。预期的结果是这样的。

但是,如果我将代码中的x=add(x)替换为x=x+1,输出始终为x = 1。看起来goroutine中的代码没有被执行。我无法理解这种行为,有什么解释吗?

英文:

Here is a piece of code, the printed value of x is an indeterminate integer, eg:
x = 359931570 , x = 325604846. The performance is expected.

package main

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

func main() {
        runtime.GOMAXPROCS(1)
        var x int = 1
        for i := 0; i < 2; i++ {
                go func() {
                        for {
                            x=add(x) // x=x+1 
                        }
                }()
        }
        time.Sleep(time.Second)
        fmt.Println("end")
        fmt.Println("x =", x)
}

func add(x int) int {
  return x+1
}

But if I replace x=add(x) with x=x+1 in the code, its output becomes always x = 1. It looks like the code in the goroutine is not executed. I can't understand this behavior, what is the explanation?

答案1

得分: 4

代码存在数据竞争,并且输出是未定义的。然而,有一种方法可以解释为什么在最后x=1

当多个goroutine更新共享变量x而没有显式同步时,不能保证其他goroutine会看到由一个goroutine对变量x的更新。因此,Go内存模型允许主goroutine从未看到其他goroutine的影响,并使用x的初始值。

当使用函数时,为什么会发生变化是有趣的。但是,这时会发生数据竞争,输出是未定义的。

英文:

The code has a data race, and the output is undefined. However, there is a way to explain why x=1 at the end.

With multiple goroutines updating the shared variable x with no explicit synchronization, there are no guarantees that other goroutines will see the updates to the variable x made by one goroutine. Thus the Go memory model allows the case where the main goroutine never sees the effects of the other goroutines, and uses the initial value of x.

Why that changes when a function is used is interesting. But then, there is a data race and the output is undefined.

huangapple
  • 本文由 发表于 2022年2月23日 10:19:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/71230616.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定