首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何解决Golang地图的并发访问问题?

如何解决Golang地图的并发访问问题?
EN

Stack Overflow用户
提问于 2018-09-26 08:07:41
回答 1查看 5K关注 0票数 2

现在我只有一张地图,只有一个写/删除戈鲁丁和许多阅读的戈鲁蒂,有一些解决方案在具有并发访问的映射上,如RWMutex,sync.map,并发映射,sync.atomic,sync.Value,对我来说,最好的选择是什么?

RWMutex的读锁有点冗余

sync.map和并发映射集中在许多写数据对象上。

EN

回答 1

Stack Overflow用户

发布于 2018-09-26 08:58:24

你的问题有点含糊不清--所以我来把它分解一下。

地图应该使用什么形式的并发访问?

选择取决于您从地图中需要的性能。我会选择一种基于简单互斥(或RWMutex)的方法。

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

再说一遍,这一切都取决于你的程序的规模和你所需要的性能。

如何使用互斥锁进行并发访问?

为了确保正确使用映射,可以将其包装在struct中。

代码语言:javascript
复制
type Store struct {
    Data              map[T]T
}

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

现在,我们将使用一组方法来实现这一点,如下所示:

代码语言:javascript
复制
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。

我建议您看看如何在戈朗使用RWMutex?

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52512915

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档