映射并发访问

61 mutex map go

在具有并发访问权限的程序中使用映射时,是否需要在函数中使用互斥锁来读取值?

Son*_*nia 93

多个读者,没有作家是好的:

https://groups.google.com/d/msg/golang-nuts/HpLWnGTp-n8/hyUYmnWJqiQJ

一位作家,没有读者可以.(否则地图不会太好.)

否则,如果至少有一个编写器至少一个编写器或读者,则所有读者编写者必须使用同步来访问该映射.互斥锁可以正常工作.


小智 47

sync.Map 已于2017年4月27日合并为Go大师.

这是我们一直在等待的并发Map.

https://github.com/golang/go/blob/master/src/sync/map.go

https://godoc.org/sync#Map

  • 好一个。请注意,新的 sync.Map 类型专为仅附加地图而设计(因此它不使用键的分片,这意味着如果您的地图有大量流失,它很可能会按照分片样式映射我上面的回答)。 (2认同)
  • @Diegomontoya当然,这里是:https://medium.com/@deckarep/the-new-kid-in-town-gos-sync-map-de24a6bf7c2c,简而言之,sync.map只有在数量时才会更快使用的核心数大于 4,如果不是这种情况,仅使用 mutext 最多会快 4 倍 (2认同)

小智 21

几天前我在这个 reddit线程中回答了你的问题:

在Go中,映射不是线程安全的.此外,例如,如果可能存在写入相同数据的另一个goroutine(同时,即),则数据甚至需要锁定.

从你在评论中的澄清来看,也会有一些setter函数,你的问题的答案是肯定的,你必须用互斥体保护你的读取; 你可以使用RWMutex.例如,您可以查看我编写的表数据结构(使用幕后地图)的实现(实际上是在reddit线程中链接的那个).

  • RW锁定适用于具有大量争用的资源,但它们比互斥锁具有更多开销.映射获取/设置足够快,以至于程序可能没有足够的争用来使更复杂的锁提供比简单的互斥锁更好的吞吐量. (9认同)
  • 谢谢你的澄清.你有没有关于此事可以推荐的论文/文章? (3认同)
  • 你能详细说一下吗?什么更适合? (2认同)
  • 但是,这篇文章的并发部分http://blog.golang.org/go-maps-in-action建议同步.RWMutex (2认同)

orc*_*man 17

您可以使用concurrent-map来为您处理并发问题.

// Create a new map.
map := cmap.NewConcurrentMap()

// Add item to map, adds "bar" under key "foo"
map.Add("foo", "bar")

// Retrieve item from map.
tmp, ok := map.Get("foo")

// Checks if item exists
if ok == true {
    // Map stores items as interface{}, hence we'll have to cast.
    bar := tmp.(string)
}

// Removes item under key "foo"
map.Remove("foo")
Run Code Online (Sandbox Code Playgroud)

  • 这样的事情就是为什么我不能认真对待"不需要仿制药"这一概念的原因. (18认同)
  • 这个概念并不是说Go"不需要泛型",而是"目前没有干净的方法来实现泛型,我们需要更多地考虑这个".例如,C++为正在使用的所有可能类型组合生成代码,这会增加编译时间和可执行文件大小的不合理数量. (12认同)