gpt4 book ai didi

go - 为什么 goroutine 的竞争条件不会在某个时候发生?

转载 作者:IT王子 更新时间:2023-10-29 01:41:23 26 4
gpt4 key购买 nike

我正在阅读 go-in-action。这个例子来自chapter6/listing09.go。

// This sample program demonstrates how to create race
// conditions in our programs. We don't want to do this.
package main

import (
"fmt"
"runtime"
"sync"
)

var (
// counter is a variable incremented by all goroutines.
counter int

// wg is used to wait for the program to finish.
wg sync.WaitGroup
)

// main is the entry point for all Go programs.
func main() {
// Add a count of two, one for each goroutine.
wg.Add(2)

// Create two goroutines.
go incCounter(1)
go incCounter(2)

// Wait for the goroutines to finish.
wg.Wait()
fmt.Println("Final Counter:", counter)
}

// incCounter increments the package level counter variable.
func incCounter(id int) {
// Schedule the call to Done to tell main we are done.
defer wg.Done()

for count := 0; count < 2; count++ {
// Capture the value of Counter.
value := counter

// Yield the thread and be placed back in queue.
runtime.Gosched()

// Increment our local value of Counter.
value++

// Store the value back into Counter.
counter = value
}
}

如果你在 play.golang.org 中运行这段代码,它将是 2,与书中相同。但是我的 mac 大部分时间打印 4,有时 2,有时甚至 3。

$ go run listing09.go 
Final Counter: 2
$ go run listing09.go
Final Counter: 4
$ go run listing09.go
Final Counter: 4
$ go run listing09.go
Final Counter: 4
$ go run listing09.go
Final Counter: 4
$ go run listing09.go
Final Counter: 2
$ go run listing09.go
Final Counter: 4
$ go run listing09.go
Final Counter: 2
$ go run listing09.go
Final Counter: 3

系统信息 go 版本 go1.8.1 darwin/amd64 macOS 山脉 苹果笔记本电脑

书上的解释(p140)

Each goroutine overwrites the work of the other. This happens when the goroutine swap is taking place. Each goroutine makes its own copy of the counter variable and then is swapped out for the other goroutine. When the goroutine is given time to exe- cute again, the value of the counter variable has changed, but the goroutine doesn’t update its copy. Instead it continues to increment the copy it has and set the value back to the counter variable, replacing the work the other goroutine performed.

根据这个解释,这段代码应该总是打印 2。

  1. 为什么我得到 4 和 3?是因为没有发生竞争条件吗?

  2. 为什么去 playground 总是得到 2?


更新:

在我设置 runtime.GOMAXPROCS(1) 后,它开始打印 2, no 4, some 3。我猜 play.golang.org 配置为具有一个逻辑处理器。

没有竞争条件的正确结果 4。一个逻辑处理器意味着一个线程。默认情况下,GO 具有与物理内核相同的逻辑处理器。因此,为什么一个线程(一个逻辑处理器)导致竞争条件,而多个线程打印正确答案?

既然我们也得到了 3 和 4 ,我们能说书上的解释是错误的吗?它如何得到 3 ? 4 是正确的。

最佳答案

根据定义,竞争条件是不确定的。这意味着虽然大多数时候您可能会得到一个特定的答案,但并非总是如此。

通过在多核上运行有趣的代码,您可以大大增加可能性的数量,从而获得更广泛的结果选择。

参见 this postthis Wikipedia article有关竞争条件的更多信息。

关于go - 为什么 goroutine 的竞争条件不会在某个时候发生?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45266393/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com