开发者社区 问答 正文

golang使用协程运行的结果不对?

package main

func main()  {

	for  _,y:=range []int{1,2,3,4,5} {
		go func() {
			print(y)
		}()
	}


	print("start...")
}

结果是

start...5555

为什么不打印12345

展开
收起
道月芬1 2021-10-18 18:02:52 416 分享 版权
阿里云 AI 助理回答

这个问题实际上与Go语言的并发机制和变量捕获有关,而非阿里云产品的直接范畴。不过,我可以帮助解释这个现象。

在你的代码中,你使用了go func()来启动goroutines(Go中的轻量级线程)来并行打印数组[]int{1,2,3,4,5}中的每个元素。但是,由于你在for循环内部启动goroutine,并且闭包函数捕获了循环变量y,这里发生了一个常见的闭包陷阱。

当循环运行时,所有的goroutines几乎同时开始执行,但它们都共享同一个y变量的内存地址。在循环结束时,y的值是5,因此所有goroutine打印的是循环结束时y的最终值,即5,而不是它们各自迭代时的值1到4。

要解决这个问题,确保每个goroutine捕获其迭代时y的独立副本,你可以通过在循环内部创建一个新的变量来实现这一点,如下所示:

package main

import "fmt"

func main() {
	for _, y := range []int{1, 2, 3, 4, 5} {
		y := y // 创建y的副本
		go func() {
			fmt.Print(y)
		}()
	}

	fmt.Println("start...")
}

在这个修改后的版本中,每次迭代都会创建一个新的y变量副本,这样每个goroutine就都能正确地打印出它应该打印的数字。不过,需要注意的是,由于goroutines的并发执行特性,"start..."的打印顺序可能仍然不固定,它可能出现在任何数字之前或之后,具体取决于goroutines的调度。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答