首页 >后端开发 >Golang >尽管在 Go 中使用了切片,为什么我的 Goroutines 都打印相同的值?

尽管在 Go 中使用了切片,为什么我的 Goroutines 都打印相同的值?

Susan Sarandon
Susan Sarandon原创
2024-12-20 02:40:10808浏览

Why Do My Goroutines All Print the Same Value Despite Using a Slice in Go?

了解数据争用中 Goroutine 的行为

提供的代码片段演示了 Go 中的经典数据争用问题。虽然目标是从字段列表中打印不同的值(“一”、“二”、“三”),但观察到的实际结果是“三”打印了三次。

要解决此问题问题,我们需要了解数据争用发生的原因和地点。

识别数据争用

问题在于Goroutine 函数的参数求值。当循环迭代数据切片时,范围变量 v 被分配给循环体并在对 v.print() 的调用中使用。然而, v 变量是元素的副本,并且由于切片在迭代过程中发生了更改,因此 goroutine 最终都指向切片的同一个最后一个元素。

这意味着当 goroutine 执行时,它们都打印最后一个值(“三”),而不是我们想要的唯一值(“一”、“二”、“三”)。

可能解决方案

有多种方法可以解决此问题并消除数据争用:

  1. 在循环内创建一个新变量:

    • 通过使用 v := v 语法在循环中声明一个新变量 v,我们确保每个 goroutine 都对自己的数据副本进行操作。
  2. 使用指针切片:

    • 而不是传递原始切片,我们可以使用指针切片(例如,[]*field)。当传递给 goroutine 时,每个指针都指向切片中的唯一元素,从而避免了数据竞争。
  3. 传递切片元素的地址:

    • 或者,我们可以使用以下方法显式地将每个切片元素的地址传递给 goroutine语法&数据[i]。这确保每个 goroutine 都有一个指向预期元素的唯一指针。
  4. 使用带参数的匿名函数:

    • 如果goroutine函数位于匿名函数内,我们可以将range变量作为参数传递给匿名函数,从而隔离goroutine 对数据的访问。

通过应用这些解决方案之一,我们可以消除数据竞争并确保 goroutine 打印预期的唯一值(“one”、“两个”、“三个”),顺序不限。

以上是尽管在 Go 中使用了切片,为什么我的 Goroutines 都打印相同的值?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn