当在m具有并发编写器的映射(包括可以从映射中删除的编写器)进行测距时,执行此操作是不是线程安全的?:
for k, v := range m { ... }
Run Code Online (Sandbox Code Playgroud)
我想要是线程安全的我需要阻止其他可能的编写器v在我读取它时更改值,并且(当使用互斥锁并且因为锁定是一个单独的步骤时)验证密钥k仍在映射中.例如:
for k := range m {
m.mutex.RLock()
v, found := m[k]
m.mutex.RUnlock()
if found {
... // process v
}
}
Run Code Online (Sandbox Code Playgroud)
(假设其他编写器m在更改之前是写锁定的v.)有更好的方法吗?
编辑添加:我知道地图不是线程安全的.但是,根据http://golang.org/ref/spec#For_statements上的Go规范,它们在某种程度上是线程安全的(搜索"如果在迭代期间删除了尚未到达的映射条目").此页面表明使用的代码range无需关心插入或删除地图的其他goroutines.我的问题是,这个线程安全性是否延伸到v,这样我v 只能使用for k, v := range m而不能使用其他线程安全机制进行读取?我创建了一些测试代码,试图迫使一个应用程序崩溃,证明这是行不通的,但即使是运行公然线程安全的代码(很多够程奋力修改与替代无锁定机制同一地图价值的)我做不到快去碰撞!