golang兩種在for循環中使用goroutine的錯誤形式


1. 閉包中使用循環體中變化的量

platground鏈接:

https://play.golang.org/p/6x6_tuQNjUO

type Value struct{
	val int
}

func (v *Value)print(){
	time.Sleep(time.Second)
	fmt.Println(v.val)
}

func main() {

	vals := make([]Value,0)

	for  i := 0; i <10;i++ {
		vals = append(vals, Value{val:i,})
	}

	for _,v := range vals{
		// 這種形式,閉包方式共享了主協程的變量v
		// 而變量v是不斷變化的,所以導致print的值都是最后一個
		go func(){
		   v.print()	
		}()
	}

	time.Sleep(time.Second*3)
}

運行結果:
9
9
9
9
9
9
9
9
9
9

2. receiver為指針時候,創建goroutine

playground鏈接:
https://play.golang.org/p/6quZIn6ZwSM

type Value struct{
	val int
}

func (v *Value)print(){
	time.Sleep(time.Second)
	fmt.Println(v.val)
}

func main() {

	vals := make([]Value,0)

	for  i := 0; i <5;i++ {
		vals = append(vals, Value{val:i,})
	}

	for _,v := range vals{
		// print方法的receiver是(*Value)類型,而此處v是一個Value類型
		// 所以每次print傳值都傳遞了&v。
		// 在for loop中,v的值變化,但是&v不會改變
		// 在其他goroutine中執行時,print的內容不可預期,取決於當時的v值
		go v.print()
	}

	time.Sleep(time.Second*3)
}
運行結果:
4
4
4
4
4


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM