Go 竞态条件场景中的不同行为

问题描述 投票:0回答:1

我试图理解为什么两段相似的代码表现不同。这两个片段都创建了大量的 goroutine,它们尝试同时附加到同一个切片,我认为这是一种竞争条件。然而,第一个片段会出现恐慌,而第二个片段则不会。

以下是片段:

片段1:

package main

func main() {
    for i := 0; i < 100000; i++ {
        var arr []int
        go func() {
            arr = append(arr, 1)
        }()
        go func() {
            arr = append(arr, 1)
        }()
    }
}

片段2:

package main

func main() {
    var arr []int
    for i := 0; i < 100000; i++ {
        go func() {
            arr = append(arr, 1)
        }()
        go func() {
            arr = append(arr, 1)
        }()
    }
}

任何人都可以帮助我理解为什么第一个片段会出现恐慌,而第二个片段却不会?预先感谢您的帮助!

go concurrency slice race-condition goroutine
1个回答
0
投票

大家都能猜到。

在第一个示例中,您生成了许多生长相同(零)切片的 goroutine 对,因此一个例程看到另一个例程未完成的结果的变化很大,这意味着部分初始化的

arr
切片。

在第二个示例中,您主要写入同一个切片,因此并发 goroutine 会覆盖另一个 goroutine 的数据,但是当一个例程追加一个元素并将新长度设置为 5 时,另一个例程会覆盖一个元素并将长度设置为 4只是有无效数据,但没有崩溃。

在这两种情况下,您都有无效数据,但由于崩溃,在第一种情况下更容易检测到,而通过

-race
标志会检测第二种情况。

请注意,竞争检测器不会检测所有数据竞争,并且不同 CPU 架构上的竞争结果有所不同,因此请注意文档中指定的假定行为。

© www.soinside.com 2019 - 2024. All rights reserved.