gpt4 book ai didi

go - 了解原子添加和互斥量

转载 作者:IT王子 更新时间:2023-10-29 01:04:00 26 4
gpt4 key购买 nike

我正在下面的处理程序函数中测试递增 itemID 的并发性,有时递增会跳过一个值(例如:4、6、7,...跳过 id 5)。

func proxyHandler() http.Handler {
var itemID int32
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
proxy := httputil.NewSingleHostReverseProxy(url)
proxy.ModifyResponse = func(res *http.Response) error {
item := Item{
ID: int(atomic.AddInt32(&itemID, 1)),
}
items.Add(item)
return nil
}
proxy.ServeHTTP(rw, req)
})
}

我使用 Mutex 解决了这个问题:

func proxyHandler() http.Handler {
itemID := 0
mux := sync.Mutex{}
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
proxy := httputil.NewSingleHostReverseProxy(url)
proxy.ModifyResponse = func(res *http.Response) error {
mux.Lock()
itemID++
item := Item{
ID: itemID,
}
items.Add(item)
mux.Unlock()
return nil
}
proxy.ServeHTTP(rw, req)
})
}

我想了解为什么 atomic add 没有像我预期的那样工作,即生成一个没有间隙的顺序值。

最佳答案

atomic.AddInt32() 非常适合多个 goroutines 并发使用。这就是它在 atomic 包中的原因。您的问题与 Items.Add() 有关,您在评论中指出它没有任何锁定保护。

这是安全 Items.Add() 的粗略定义

type Items struct {
items []Item
lock sync.Mutex
}

func (i *Items) Add(item Item) {
i.lock.Lock()
defer i.lock.Unlock()
i.items = append(i.items, item)
}

有了上面的 Items 定义,您现在可以将初始代码与 atomic.AddInt32() 一起使用。但是,我想指出的是,您不能在其他线程附加到它时读取 Items。甚至读取也必须同步。

关于go - 了解原子添加和互斥量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53350749/

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