【发布时间】:2017-12-18 08:04:23
【问题描述】:
我在使用 Go 的 sync.Map 时遇到问题。详情如下:
我创建了一个全局同步地图,例如:
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)
现在将有多个线程将访问此地图并执行一些操作。内部同步映射将不断更新。一旦对内部同步映射的键进行了处理,该键将从该映射中删除。
一旦内部同步映射变空,我就知道作业完成了。
现在由于有多个线程访问此地图,我收到了恐慌:
致命错误:并发读写
我仍然想知道,即使在使用 sync map 之后我也面临这个问题。
谁能指出我做错了什么?
【问题讨论】:
-
请提供代码示例来显示您的错误。好像您正在创建法线贴图(例如使用
make(map[string]interface{})并以并发方式访问它们。 -
@ArmanOrdookhani 更新了问题。
-
recSet是否会在某些 goroutine 之间共享?尝试像go run -race main.go这样运行您的代码,以获取您同时访问地图的位置的堆栈跟踪。 -
使用比赛检测器。 sync.Map 不会神奇地使其内容对并发读写安全
-
向我们展示执行
delete()的部分。注意那部分。我敢打赌,您会自己发现问题所在...
标签: go concurrency hashmap synchronization