【问题标题】:How to safely allow current access to nested maps in go?如何安全地允许当前访问嵌套地图?
【发布时间】:2020-06-10 13:08:19
【问题描述】:

我对如何确保安全地并发访问嵌套地图感到有些困惑。 最初我的设置是这样的,我意识到我需要能够锁定至少一张地图。

map[string]map[string]Dish

经过一番思考,我设想的结构如下所示:

type Manager struct {
    mu sync.RWMutex
    locations map[string]Restaurant
}
type Restaurant struct {
    mu sync.RWMutex
    menu map[string]Dish
}
type Dish struct {
    name string
    price string
    vegan bool
}

我的基本理解如下: 如果我想向locations 添加一个新的Restaurant,我需要锁定Manager。 如果我想将Dish 添加或修改为menu,我需要锁定Restaurant,但我不确定是否还需要锁定Manager。 同样,如果我想访问来自Manager 的值,我不确定是否也需要锁定Restaurant

我已经尝试(未成功)在使用 -race 标志时强制数据竞争,所以我不确定是否随时锁定 Manager Restaurant 发生突变,并且每次访问 @987654337 时锁定 Restaurant @ 是必要的,或者如果我试图强制比赛没有奏效。

【问题讨论】:

  • 不应该互斥量作为指针正常工作吗?您最好添加代码以显示您如何锁定并确保您没有锁定不同的互斥锁
  • @AlexanderTrakhimenok : stackoverflow.com/a/28244472/1286423 你应该使用指向互斥体的指针。

标签: dictionary go concurrency nested-map


【解决方案1】:

首先,你不想复制锁,所以你需要使用指针:

type Manager struct {
    mu sync.RWMutex
    locations map[string]*Restaurant
}
type Restaurant struct {
    mu sync.RWMutex
    menu map[string]Dish
}

一旦你有一个*Restaurant 实例,你必须锁定它以写入menu,并锁定它以读取menu

要通过地图查找获得餐厅,您需要锁定Manager,而要向Manager 添加内容,则需要锁定它。

所以如果你想从上到下,你必须先锁定经理,然后再锁定餐厅。每次执行此操作时,您还必须确保以相同的顺序锁定它们(首先是经理,其次是餐厅)以避免死锁。

【讨论】:

  • 谢谢,关于指针的要点。我仍然认为“地图是一个指针”,但餐厅是一个结构而不是地图。这非常简洁地回答了我的问题,非常感谢!
  • @jimpeter 您也可以查看sync.Map,但请确保您已仔细阅读注意事项。 (不过,您自己实现它完全没问题。)
猜你喜欢
  • 2010-10-06
  • 2022-01-15
  • 1970-01-01
  • 2021-11-19
  • 1970-01-01
  • 2011-04-16
  • 1970-01-01
  • 2015-05-13
相关资源
最近更新 更多