首页 >后端开发 >Golang >Go 的'range”关键字对于并发地图访问安全吗?

Go 的'range”关键字对于并发地图访问安全吗?

Barbara Streisand
Barbara Streisand原创
2024-12-07 04:54:16595浏览

Is Go's `range` Keyword Safe for Concurrent Map Access?

在 Go 中使用“范围”并发访问地图

在“Go 地图实际应用”博客条目中,文档指出映射如果没有像sync.RWMutex这样的同步机制,并发使用是不安全的。但是,目前尚不清楚通过范围迭代进行的访问是否构成“读取”,或者范围关键字是否有特定的锁定要求。

范围的并发

范围表达式为在循环开始之前评估一次。对于映射,这意味着映射变量(例如 testMap)仅计算一次,即使在迭代期间可能添加或删除新的键值对。初始评估和迭代本身之间的这种分离意味着执行迭代时 for 语句不会访问映射。

安全迭代

因此,以下迭代对于并发访问是安全的:

func IterateMapKeys(iteratorChannel chan int) error {
    testMapLock.RLock()
    defer testMapLock.RUnlock()
    mySeq := testMapSequence
    for k, _ := range testMap {
        ....
    }
    return nil
}

这种设计确保地图仅在必要时才被锁定,同时允许并发访问其他

并发修改

但是,这种类型的锁定仅阻止并发访问,而不能阻止并发修改。即使迭代正在进行时,另一个 goroutine 也可能获取写锁并修改映射。为了防止这种情况,地图应该在整个迭代过程中保持锁定状态。

示例

此示例演示了 for 块中解锁和锁定之间的区别:

func IterateMapKeys(iteratorChannel chan int) error {
    testMapLock.RLock()
    defer testMapLock.RUnlock()
    mySeq := testMapSequence
    for k, _ := range testMap {
        testMapLock.RUnlock()
        ....
        testMapLock.RLock()
        ....
    }
    return nil
}

在此示例中,释放 for 块内的读锁允许并发修改和潜在的错误。

结论

range 关键字本身不提供对地图的并发访问的同步。使用正确的同步机制(例如sync.RWMutex)对于确保并发迭代和修改的安全性至关重要。

以上是Go 的'range”关键字对于并发地图访问安全吗?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn