[Go] 解決go的fatal error: concurrent map writes map非並發安全


map不是並發安全的 , 當有多個並發的groutine讀寫同一個map時 

會出現panic錯誤

concurrent map writes

 

例如下面的代碼會出現這個錯誤:

var mMap map[int]int

func TestMyMap(t *testing.T) {
    mMap = make(map[int]int)

    for i := 0; i < 5000; i++ {
        go func() {
            mMap[i] = i
        }()
        go readMap(i)
    }
}
func readMap(i int) int {
    return mMap[i]
}

解決這個錯誤可以有多種方式 , 現在采取讀寫鎖的方式 ,

並發訪問map是不安全的,會出現未定義行為,導致程序退出。所以如果希望在多協程中並發訪問map,必須提供某種同步機制,一般情況下通過讀寫鎖sync.RWMutex實現對map的並發訪問控制,將map和sync.RWMutex封裝一下,可以實現對map的安全並發訪問

改造后的代碼

type SMap struct {
    sync.RWMutex
    Map map[int]int
}

func (l *SMap) readMap(key int) (int, bool) {
    l.RLock()
    value, ok := l.Map[key]
    l.RUnlock()
    return value, ok
}

func (l *SMap) writeMap(key int, value int) {
    l.Lock()
    l.Map[key] = value
    l.Unlock()
}

var mMap *SMap

func TestMyMap(t *testing.T) {
    mMap = &SMap{
        Map: make(map[int]int),
    }

    for i := 0; i < 5000; i++ {
        go func() {
            mMap.writeMap(i, i)
        }()
        go readMap(i)
    }
}
func readMap(i int) (int, bool) {
    return mMap.readMap(i)
}

 有這三種方式:

1.使用channel
2.使用sync.map
3.使用map但必須進行加鎖


免責聲明!

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



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