英文:
Confusing performance about two pieces of code with go goroutines
问题
这是一段代码,打印出的x的值是一个不确定的整数,例如:x = 359931570,x = 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论