gpt4 book ai didi

go - 在 sync.Map 中是否有必要使用 Load 后跟 LoadOrStore 来获取复杂值

转载 作者:IT王子 更新时间:2023-10-29 01:08:28 25 4
gpt4 key购买 nike

在代码中,具有昂贵的生成值结构的全局映射可能会被多个并发线程修改,哪种模式是正确的?

// equivalent to map[string]*activity where activity is a
// fairly heavyweight structure
var ipActivity sync.Map

// version 1: not safe with multiple threads, I think
func incrementIP(ip string) {
val, ok := ipActivity.Load(ip)
if !ok {
val = buildComplexActivityObject()
ipActivity.Store(ip, val)
}

updateTheActivityObject(val.(*activity), ip)
}

// version 2: inefficient, I think, because a complex object is built
// every time even through it's only needed the first time
func incrementIP(ip string) {
tmp := buildComplexActivityObject()
val, _ := ipActivity.LoadOrStore(ip, tmp)
updateTheActivity(val.(*activity), ip)
}

// version 3: more complex but technically correct?
func incrementIP(ip string) {
val, found := ipActivity.Load(ip)
if !found {
tmp := buildComplexActivityObject()

// using load or store incase the mapping was already made in
// another store
val, _ = ipActivity.LoadOrStore(ip, tmp)
}
updateTheActivity(val.(*activity), ip)
}

版本三是给定 Go 的并发模型的正确模式吗?

最佳答案

选项 1 显然可以由多个具有新 ip 的 goroutines 同时调用,并且只会存储 if block 中的最后一个。 buildComplexActivityObject 花费的时间越长,这种可能性就会大大增加,因为关键部分的时间越多。

选项 2 有效,但每次都调用 buildComplexActivityObject,您声明这不是您想要的。

鉴于您希望尽可能不频繁地调用 buildComplexActivityObject,第三个选项是唯一有意义的选项。

然而,sync.Map 无法保护存储指针引用的实际 activity 值。更新 activity 值时,您还需要在那里进行同步。

关于go - 在 sync.Map 中是否有必要使用 Load 后跟 LoadOrStore 来获取复杂值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51103621/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com