for循環+goroutine的坑

for循環+goroutine的坑 (Golang中Routine闭包中的一个坑/協程引用迴圈變數的問題)

  • 主協程的迴圈很快就跑完了,而各個協程才開始跑,此時 i 的值可能會重複出現指向最後一個值

func testRoutine() { //Golang中Routine闭包中的一个坑
	for i := 0; i < 100; i++ {
		go func() { //这是因为很有可能当 for-loop 执行完之后 goroutine 才开始执行,这个时候 val 的值指向切片中最后一个元素。
			fmt.Println(i) //值可能是0-100中的任意数字的,有一些可能会重复出现-->引用传递(同一个对象)给了子协程
		}()
	}
	time.Sleep(1 * time.Second)
}

解決方法

  • 將參數傳進go func(xxxx)

func testRoutineFix2() {
	for i := 0; i < 100; i++ {
		go func(ii int) {
			fmt.Println(ii)
		}(i) //参数都是通过值传递进行传递的
	}
	time.Sleep(1 * time.Second)
}
  • 另一種方法是在循環內定義新的變量,由於在循環內定義的變量在循環遍歷的過程中是不共享的

完整程式碼

Last updated