gpt4 book ai didi

dictionary - 如何解决Golang map的并发访问?

转载 作者:数据小太阳 更新时间:2023-10-29 03:34:21 24 4
gpt4 key购买 nike

现在我有一个只有一个写入/删除 goroutine 和许多读取 goroutine 的映射,Map with concurrent access 上有一些解决方案, 例如 RWMutex, sync.map, concurrent-map , sync.atomic, sync.Value,什么对我来说是最好的选择?

RWMutex的读锁有点多余

sync.map 和 concurrent-map 专注于许多写 goroutine

最佳答案

你的问题有点含糊 - 所以我会分解它。

What form of concurrent access should I use for a map?

选择取决于您对 map 的性能要求。我会选择基于简单互斥锁(或 RWMutex)的方法。

当然,您可以从 concurrent map 获得更好的性能. sync.Mutex 锁定 所有 映射桶,而在并发映射中,每个桶都有自己的 sync.Mutex

同样 - 这完全取决于您的程序规模和您需要的性能。

How would I use a mutex for concurrent access?

为确保正确使用 map ,您可以将其包装在 struct 中。

type Store struct {
Data map[T]T
}

这是一个更面向对象的解决方案,但它使我们能够确保同时执行任何读/写操作。除此之外,我们还可以轻松存储其他可能对调试或安全有用的信息,例如作者。

现在,我们将使用如下一组方法来实现它:

mux sync.Mutex

// New initialises a Store type with an empty map
func New(t, h uint) *Store {
return &Store{
Data: map[T]T{},
}
}

// Insert adds a new key i to the store and places the value of x at this location
// If there is an error, this is returned - if not, this is nil
func (s *Store) Insert(i, x T) error {
mux.Lock()
defer mux.Unlock()
_, ok := s.Data[i]
if ok {
return fmt.Errorf("index %s already exists; use update", i)
}
s.Data[i] = x
return nil
}

// Update changes the value found at key i to x
// If there is an error, this is returned - if not, this is nil
func (s *Store) Update(i, x T) error {
mux.Lock()
defer mux.Unlock()
_, ok := s.Data[i]
if !ok {
return fmt.Errorf("value at index %s does not exist; use insert", i)
}
s.Data[i] = x
return nil
}

// Fetch returns the value found at index i in the store
// If there is an error, this is returned - if not, this is nil
func (s *Store) Fetch(i T) (T, error) {
mux.Lock()
defer mux.Unlock()
v, ok := s.Data[i]
if !ok {
return "", fmt.Errorf("no value for key %s exists", i)
}
return v, nil
}

// Delete removes the index i from store
// If there is an error, this is returned - if not, this is nil
func (s *Store) Delete(i T) (T, error) {
mux.Lock()
defer mux.Unlock()
v, ok := s.Data[i]
if !ok {
return "", fmt.Errorf("index %s already empty", i)
}
delete(s.Data, i)
return v, nil
}

在我的解决方案中,我使用了一个简单的 sync.Mutex - 但您可以简单地更改此代码以适应 RWMutex。

我建议你看看How to use RWMutex in Golang? .

关于dictionary - 如何解决Golang map的并发访问?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52512915/

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