首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >golang sync.Map Range函数线程安全吗?

golang sync.Map Range函数线程安全吗?
EN

Stack Overflow用户
提问于 2019-01-14 08:53:08
回答 2查看 5K关注 0票数 1

doc

代码语言:javascript
复制
Range does not necessarily correspond to any consistent snapshot of the 
Map's contents: no key will be visited more than once, but if the value 
for any key is stored or deleted concurrently, Range may reflect any 
mapping for that key from any point during the Range call.

这是否意味着在range调用期间不会调用读锁,并且用户必须实现自己的互斥锁才能使Range调用是线程安全的?

EN

回答 2

Stack Overflow用户

发布于 2019-01-14 10:38:48

阅读所有文档,包括这一部分。

Package sync

导入"sync“

type Map 1.9

Map类似于Go mapinterface{}interface{},但对于多个goroutine的并发使用是安全的,无需额外的锁定或协调。加载、存储和删除在分期不变的时间内运行。

Map类型是专门化的。大多数代码应该使用普通的Go map,使用单独的锁定或协调,以获得更好的类型安全性,并使维护与map内容一起的其他不变量变得更容易。

Map类型针对两种常见用例进行了优化:(1)当给定键的条目只写入一次,但多次读取时,例如在只增长的缓存中;(2)当多个goroutines读取、写入和覆盖不相交的键集的条目时。在这两种情况下,与与单独的互斥或RWMutex配对的Go映射相比,使用映射可以显著减少锁争用。

通过设计,sync.Map是线程安全的。sync.Map是一种特殊用途的地图,用途有限。

大多数代码应该使用普通的Go映射,带有单独的锁定或协调,以获得更好的类型安全性,并使维护其他不变量和映射内容变得更容易。

不要向sync.Map添加额外的锁定层。使用不同的算法或遵循建议,使用带有单独锁定或协调的普通Go map

Package sync

导入"sync“

函数(*Map)范围1.9

func (m *Map) Range(f func(key,value interface{}) bool)

对于映射中存在的每个键和值,Range依次调用f。如果f返回false,range将停止迭代。

Range不一定对应于Map内容的任何一致快照:任何键都不会被多次访问,但如果同时存储或删除任何键的值,Range可能会从Range调用期间的任何点反映该键的任何映射。

即使f在恒定的调用次数之后返回false,映射中的元素数量的范围也可以是O(N)。

sync.Map Range上的弱不变量意味着它通常不是很有用。

票数 3
EN

Stack Overflow用户

发布于 2019-01-14 09:46:44

你说得太对了。

基本上,这与您使用for的方式相同:您只需预先获取一个计数,然后迭代您期望存在的每个值。

理想情况下,如果您必须担心映射上的并发性,那么您应该创建一个副本,然后进行迭代,或者围绕它实现一个sync.Mutex

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54174618

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档