Получение блокировки по адресу памяти вместо переменной в golang - PullRequest
0 голосов
/ 21 апреля 2019

У меня есть интерфейс под названием Setter. Структура с именем SetterImpl реализует этот интерфейс и имеет 2 сеттера, каждый из которых устанавливает 2 интерфейса.

type Setter interface {
    A() *AInterface
    B() *BInterface
}
type SetterImpl struct {
    a *AInterface
    b *BInterface
}

func (s *SetterImpl) A(a *AInterface) {
    a = a
}

func (s *SetterImpl) B(b *AInterface) {
    b = b
}

func returnSetter(a *AInterface, b *BInterface) Setter {
    return &SetterImpl{a:a, b:b}
}

Сеттер, возвращенный вышеуказанным методом, находится в куче (скажем, SHeap) и отправлен на сервер gRPC. Теперь я хочу обновить a и b в SetterImpl так, чтобы сервер gRPC использовал новые значения.

Итак, у меня сейчас 2 программы; один из них - это основная процедура сервера gRPC (скажем, MAIN), другой - разветвленный (скажем, FORKED), который просто предназначен для обновления полей установщика.

Если я использую Mutex в FORKED, это, по сути, добавляет забор (например, Java). На самом деле он не блокирует никакие переменные (кроме себя). Я не хочу, чтобы MAIN мог читать a и b, хранящиеся в SHeap, пока FORKED обновляет их. Потоки API (goroutines) на сервере не получают Read Mutex перед чтением значений в SHeap. Итак, возможно ли сделать то, что я пытаюсь достичь? Если да, как мне этого добиться?

Ответы [ 2 ]

1 голос
/ 22 апреля 2019

Я не думаю, что вы можете заблокировать переменные в Go.Вы можете заблокировать только часть кода.

m.Lock()
// do stuff
m.Unlock()

Вы создаете для себя проблему из ничего, используя шаблон "interface" против "Impl".

Вы можете сделать свою жизньпроще, просто используя обычную функцию.Затем вы можете установить блокировку внутри функции и быть уверенным, что она будет защищена.

Поскольку вы создаете интерфейс, вы не можете ничего гарантировать в отношении содержимого функции, реализующей интерфейс.

0 голосов
/ 22 апреля 2019

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

mux.RLock()
defer mux.RUnlock()

в методах получения a и b в SetterImpl.И когда я хочу установить a и b в FORKED, я использовал

mux.Lock()
defer mux.Unlock()

Таким образом, если FORKED получает блокировку записи, в это время блокировка чтения не может быть получена.Это возможно, так как поле RWLock, созданное в SHeap, используется в качестве глобальной переменной (то есть этот мьютекс никогда не изменяется и передается FORKED)

...