Как безопасно разрешить текущий доступ к вложенным картам в go? - PullRequest
0 голосов
/ 26 февраля 2020

Я немного озадачен тем, как обеспечить безопасный параллельный доступ к вложенным картам. Первоначально мои настройки были такими, но я понимаю, что мне нужно иметь возможность заблокировать хотя бы одну из карт.

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
}

Мое базовое понимание c следующее: если я хочу добавить новый Restaurant к locations, мне нужно заблокировать Manager. Если бы я хотел добавить или изменить Dish в menu, мне нужно было бы заблокировать Restaurant, но я не уверен, нужно ли мне также блокировать Manager. Точно так же, если бы я хотел получить доступ к значениям из Manager, я не уверен, нужно ли мне также блокировать Restaurant.

Я пытался (безуспешно) принудить гонки данных при использовании флаг -race, поэтому я не уверен, что блокировка Manager в любое время Restaurant изменена, и блокировка Restaurant каждый раз, когда я получаю доступ к Manager, необходима, или если мои попытки форсировать гонку не сработали .

1 Ответ

1 голос
/ 26 февраля 2020

Во-первых, вы не хотите копировать блокировки, поэтому вам нужно использовать указатели:

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, вам необходимо заблокировать его .

Итак, если вы хотите начать сверху и go снизу, вам нужно заблокировать как менеджера, так и ресторан. Вы также должны убедиться, что блокируете их в том же порядке (сначала менеджер, затем ресторан), чтобы избежать тупиков.

...