【问题标题】:Facing concurrency issues with Go sync mapsGo 同步地图面临并发问题
【发布时间】: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


【解决方案1】:

我发现了代码的问题所在。我使用 sync.Map 作为值类型而不是指针。

所以,我正在制作底层互斥体的副本。并且在读/写操作中,锁是在副本上而不是原来的互斥体上。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-12
    • 2019-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-04
    相关资源
    最近更新 更多