2017-12-18 316 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作为值类型而不是指针。

所以,我正在制作底层互斥体的副本。在读/写操作时,锁定位于副本而不是原始互斥体。

更改地图以使用指针解决了问题。