golang使用閉包時的共享變量問題

在併發的使用golang閉包的時候有一個共享變量問題要注意一下,看一段代碼golang

package main

import (
	"fmt"
	"sync"
)

func main() {
	var (
		wg    sync.WaitGroup
	)

	for i := 0; i < 5; i++ {
		wg.Add(1)
		go func() {
			fmt.Println(i)
			wg.Done()
		}()
	}
	wg.Wait()
}

輸出結果閉包

5
5
5
5
5

???什麼狀況,爲何不是0 ~ 4 的亂序組合?架構

由於主協程和子協程是有執行順序的,也就是使用主協程在一個時間片(不太明白的話,能夠看看CPU調度的相關資料,原理相似)內徹底是本身的show time,當它時間片用完以後,才輪到子協程執行,而這個時候,變量「i」已是5了。併發

怎麼避免這個問題,有兩種方式。code

第一種,將「i」付給一個臨時變量。協程

package main

import (
	"fmt"
	"sync"
)

func main() {
	var (
		wg    sync.WaitGroup
	)

	for i := 0; i < 5; i++ {
		t:=i
		wg.Add(1)
		go func() {
			fmt.Println(t)
			wg.Done()
		}()
	}
	wg.Wait()
}

第二種,傳參數it

package main

import (
	"fmt"
	"sync"
)

func main() {
	var (
		wg    sync.WaitGroup
	)

	for i := 0; i < 5; i++ {
		wg.Add(1)
		go func(t int) {
			fmt.Println(t)
			wg.Done()
		}(i)
	}
	wg.Wait()
}

好了,就這麼簡單。import

留一個小問題,爲何第一段代碼輸出的是5而不是4呢?變量

更多架構、PHP、GO相關踩坑實踐技巧請關注個人公衆號:PHP架構師原理

相關文章
相關標籤/搜索