英文:
Is this a right way to update a global golang map with concurrent read?
问题
这是一个致命错误:并发地读取和写入映射的演示代码:
package main
var Map = make(map[int]int)
func main() {
for i := 0; i < 100000; i++ {
go updateMap()
go readMap(i)
}
}
func readMap(key int) int {
return Map[key]
}
func updateMap() {
for j := 0; j < 1000; j++ {
Map[j] = j
}
}
我没有使用锁或sync.Map,只是使用临时变量替换全局映射,这样就不会发生panic,代码如下:
package main
var Map = make(map[int]int)
func main() {
for i := 0; i < 100000; i++ {
go updateMap()
go readMap(i)
}
}
func readMap(key int) int {
return Map[key]
}
func updateMap() {
tmp := map[int]int{}
for j := 0; j < 1000; j++ {
tmp[j] = j
}
Map = tmp
}
这种更新全局映射的方式有问题吗?
英文:
this is a fatal error: concurrent map read and map write demo code:
package main
var Map = make(map[int]int)
func main() {
for i := 0; i < 100000; i++ {
go updateMap()
go readMap(i)
}
}
func readMap(key int) int {
return Map[key]
}
func updateMap() {
for j := 0; j < 1000; j++ {
Map[j] = j
}
}
I don't use the lock or sync.Map, just use tmp var to replace global map, it will not panic, codes like this:
package main
var Map = make(map[int]int)
func main() {
for i := 0; i < 100000; i++ {
go updateMap()
go readMap(i)
}
}
func readMap(key int) int {
return Map[key]
}
func updateMap() {
tmp := map[int]int{}
for j := 0; j < 1000; j++ {
tmp[j] = j
}
Map = tmp
}
Is there any problem with this way to update the global map?
答案1
得分: 1
更新地图的第二种方式不会引发恐慌,因为被更新的地图是一个临时地图,但仍然存在竞争条件。在updateMap
函数之后,无法保证其他goroutine何时会看到updateMap
的效果,如果有的话。
正确的方式是对两种情况都使用RWMutex
。readMap
应该使用RLock/RUnlock
,而updateMap
应该使用Lock/Unlock
。对于第二种情况,如果updateMap
是唯一更新地图的goroutine,你可以在复制阶段使用Rlock/RUnlock
,在分配地图时使用Lock/Unlock
。
英文:
The second way of updating the map will not panic, because the map being updated is a temporary map, but there is still a race condition. After the updateMap
function, there is no guarantee when the other goroutine will see the effects of updateMap
, if ever.
The correct way is to use a RWMutex
for both cases. The readMap
should use RLock/RUnlock
, and updateMap
should use Lock/Unlock
. For the second case, if the updateMap
the only goroutine that ever updates the map, you can use Rlock/RUnlock
during the copy phase, and Lock/Unlock
when you assign the map.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论