英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论