如何安全地允许当前访问go中的嵌套地图?

时间:2020-02-26 15:49:43

标签: dictionary go concurrency nested-map

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

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
}

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

在尝试使用Restaurant标志时,我试图(未成功)强制进行数据争用,所以我不确定是否-race时锁定Manager的任何时间都发生了变化,而锁定{{ 1}}是每次我访问Restaurant所必需的,或者如果我尝试强行比赛的尝试无效。

1 个答案:

答案 0 :(得分: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添加东西,您需要将其锁定。

因此,如果要从顶部开始然后再到底部,则必须同时锁定经理和餐厅。您还必须确保每次执行此操作时都锁定它们的顺序相同(首先是经理,然后是餐厅),以避免死锁。