1. 程式人生 > >go語言對映map的執行緒協程安全問題

go語言對映map的執行緒協程安全問題

見程式碼中註釋:
package main

import (
       "fmt"
       "sync"
)

func main()  {

       m := map[string]int{"a":1, "b":2, "c":3, "d":4, "e":5, "f":6}

       fmt.Println(m)
       fmt.Println("-------")

       wg := &sync.WaitGroup{}
       wg.Add(3)
       go func(p map[string]int) {

              
defer wg.Done() p["a"] = 10 }(m) //因為go語言中的map為引用型別, 雖然go語言函式以傳值方式呼叫,即函式持有的為引數副本,但因是引用型別, 故依然指向對映m , 類似c的指標.go func(p map[string]int) { defer wg.Done() p["a"] = 11 }(m) go func(p map[string]int) { defer wg.Done() p["a"] = 12
}(m) wg.Wait() fmt.Println(m)
/*
因為map為引用型別,所以即使函式傳值呼叫,引數副本依然指向對映m, 所以3個goroutine併發寫同一個對映m, 寫過多執行緒程式的同學都知道,對於共享變數,資源,
併發讀寫會產生競爭的, 故共享資源遭到破壞, 所以要麼加鎖, 要麼用channel排隊序列化, 總之要排他訪問。
所以切記: 多goroutine讀寫同一個對映時, 要保護喲, 加鎖也可, 利用channel序列化處理也可!!!
*/
}
注意: 此文章只是我個人筆記, 如有錯漏,請一定指正, 共同學習, 我的郵箱: [email protected]