Go 中使用 range 关键字并发访问地图的概念经常被误解。为了澄清这个问题,让我们探讨一下并发访问映射的复杂性以及使用范围的含义。
for 语句中的范围表达式仅在循环之前计算一次开始,排除某些特定场景。对于映射,范围表达式仅指向映射变量。
在范围迭代期间,键和值变量(大多数情况下为 k 和 v)在每次迭代期间保存地图中的值。但是,执行迭代时,for 块内不会发生映射访问。当为下一次迭代设置 k 和 v 值时,就会发生这种情况。
理解这些概念,通过使用锁来保护,在映射上执行并发迭代是安全的迭代期间的地图。然而,迭代中的解锁应该作为延迟语句来完成,以处理早期返回。
var testMap = make(map[int]int) var testMapLock = &sync.RWMutex{} func IterateMapKeys(iteratorChannel chan int) error { testMapLock.RLock() defer testMapLock.RUnlock() for k, v := range testMap { testMapLock.RUnlock() someFunc() testMapLock.RLock() if someCond { return someErr } } return nil }
值得注意的是,这种类型的锁定方案只能防止并发访问。它不会阻止其他 goroutine 的并发修改。但是,如果修改受到写锁的保护,它们仍然是安全的,但 for 循环不一定会迭代新的对。
解锁 for 块中的读锁是不安全的,因为它允许其他 goroutine 修改映射并可能导致竞争条件。
以上是使用'range”对 Go Map 进行并发迭代安全吗?如何实现?的详细内容。更多信息请关注PHP中文网其他相关文章!