2017-12-18 326 views
1

我遇到了Go的sync.Map問題。以下是詳細內容:面對Go同步映射的併發問題

我創建了一個全球同步的地圖,如:

var MySyncGlobalMap = sync.Map{} 

和事件我填充這個地圖與預期結構 map[int64]map[string]interface{}。所以基本上我想填充同步圖與關鍵作爲int64和價值作爲另一同步圖結構map[string]interface{}。下面是我如何填充地圖:

//below is the innerSync map. recSet is returned from DB call in the format : []map[string]interface{} 
var innerSyncMap = sync.Map{} 
for _, record := range recSet { 

    sKey := record["key"].(string) 
    value := record["value"] 
    innerSyncMap.Store(sKey, value) 
} 
MySyncGlobalMap.Store(jobID, innerSyncMap) 

現在會有多個線程將被訪問該地圖,並做一些操作。將會不斷更新內部同步映射。一旦內部同步映射的鍵完成處理,該鍵將從該映射中刪除。

一旦內部同步映射變爲空白,我就會知道一個作業完成。

現在,因爲有多個線程訪問該映射我收到了恐慌:

Fatal error: concurrent read and write

我還是想知道,即使使用同步映射後我面對這個問題。

任何人都可以指出我做錯了什麼?

+2

請提供顯示錯誤的代碼示例。看起來像你正在創建普通地圖(例如,使用'make(map [string] interface {}')並以同時的方式訪問它們。 –

+0

@ArmanOrdookhani更新了這個問題。 –

+1

一些goroutines之間有'recSet'共享嗎?試着像'go run -race main.go'那樣運行你的代碼來獲取你正在訪問地圖的地方的棧跟蹤。 –

回答

1

我想出了代碼的問題。我使用sync.Map作爲值類型而不是指針。

所以,我正在製作底層互斥體的副本。在讀/寫操作時,鎖定位於副本而不是原始互斥體。

更改地圖以使用指針解決了問題。