使用Go同步映射面对并发问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Go同步映射面对并发问题相关的知识,希望对你有一定的参考价值。

我和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作为Value类型而不是指针。

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

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

以上是关于使用Go同步映射面对并发问题的主要内容,如果未能解决你的问题,请参考以下文章

go语言学习笔记 — 进阶 — 并发编程:同步sync,竞态检测 —— 检测代码在并发环境下出现的问题

[Go] 并发和并行的区别

golang代码片段(摘抄)

Go并发编程之美-CAS操作

Go并发编程之传统同步—互斥锁

Go语言同步编程:别再让你的Goroutine睡大觉了!