gpt4 book ai didi

go - 在读取和修改之前锁定 slice

转载 作者:行者123 更新时间:2023-12-05 09:01:12 26 4
gpt4 key购买 nike

我最近使用 Go 的经验,在审查一些代码时,我发现虽然它被写保护,但读取数据时存在问题。不是读取本身,而是读取和修改 slice 之间可能发生的修改。

type ConcurrentSlice struct {
sync.RWMutex
items []Item
}

type Item struct {
Index int
Value Info
}

type Info struct {
Name string
Labels map[string]string
Failure bool

}

如前所述,写作以这种方式受到保护:


func (cs *ConcurrentSlice) UpdateOrAppend(item ScalingInfo) {
found := false
i := 0
for inList := range cs.Iter() {
if item.Name == inList.Value.Name{
cs.items[i] = item
found = true
}
i++
}
if !found {
cs.Lock()
defer cs.Unlock()

cs.items = append(cs.items, item)
}
}

func (cs *ConcurrentSlice) Iter() <-chan ConcurrentSliceItem {
c := make(chan ConcurrentSliceItem)

f := func() {
cs.Lock()
defer cs.Unlock()
for index, value := range cs.items {
c <- ConcurrentSliceItem{index, value}
}
close(c)
}
go f()

return c
}

但是在收集 slice 的内容和修改它之间,可能会发生修改。可能是另一个例程修改了同一个 slice ,当该赋值时,它已经不存在了:slice[i ] = 项目

处理这个问题的正确方法是什么?

我已经实现了这个方法:

func GetList() *ConcurrentSlice {
if list == nil {
denylist = NewConcurrentSlice()
return denylist
}
return denylist
}

我是这样使用它的:

concurrentSlice := GetList()
concurrentSlice.UpdateOrAppend(item)

但我知道在获取和修改之间,即使它实际上是立即的,另一个例程也可能修改了 slice 。以原子方式执行这两个操作的正确方法是什么?我阅读的 slice 100% 是我修改的 slice 。因为如果我尝试将一个项目分配给一个不再存在的索引,它会中断执行。

提前致谢!

最佳答案

您进行阻止的方式是不正确的,因为它不能确保您退回的元素没有被移除。在更新的情况下,数组仍将至少保持相同的长度。

一个更简单的可行解决方案如下:

func (cs *ConcurrentSlice) UpdateOrAppend(item ScalingInfo) {
found := false
i := 0
cs.Lock()
defer cs.Unlock()

for _, it := range cs.items {
if item.Name == it.Name{
cs.items[i] = it
found = true
}
i++
}
if !found {
cs.items = append(cs.items, item)
}
}

关于go - 在读取和修改之前锁定 slice ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73859360/

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