当在m具有并发编写器的地图(包括可能会从该地图中删除的写入器)上进行遍历时,这样做不是线程安全的吗?
for k, v := range m { ... }
我以为是线程安全的,因此我需要防止其他可能的编写者v在读取值时更改其值,并且(在使用互斥锁且由于锁定是一个单独的步骤时)请验证键k是否仍在映射中。例如:
for k := range m {
m.mutex.RLock()
v, found := m[k]
m.mutex.RUnlock()
if found {
... // process v
}
}
(假设其他作者m在更改之前处于写锁定状态v。)是否有更好的方法?
编辑添加:我知道映射不是线程安全的。但是,根据http://golang.org/ref/spec#For_statements上的Go规范,它们以一种方式是线程安全的(搜索“如果在迭代过程中删除了尚未到达的映射条目”)。此页面表明,使用的代码range无需担心其他goroutine插入到地图或从地图删除的情况。我的问题是,此线程安全性是否扩展到v,这样我v 只能使用for k, v := range m并没有其他线程安全机制?我创建了一些测试代码来试图迫使应用程序崩溃以证明它不起作用,但是即使运行公然线程不安全的代码(很多goroutine在没有适当的锁定机制的情况下疯狂地修改了相同的映射值)进入崩溃!
温温酱
慕尼黑8549860
相关分类