Управление срезами с мьютексом для производительности в Голанге - PullRequest
0 голосов
/ 05 июня 2018

У меня есть следующая структура:

type User struct {
    Mutex sync.RWMutex
    Username string
    Stuff map[string]string
}

У меня также есть глобально следующее

var MyUsers []User
var UserMutex sync.RWMutex

Поскольку мое приложение обращается к срезу MyUsers тысячи раз в секунду, я подумалэто был бы лучший способ управлять производительностью.Если я хочу изменить отдельный элемент MyUsers, то я блокирую этот конкретный элемент с помощью:

MyUsers[x].Mutex.Lock()

Затем выполняйте любые изменения и разблокируйте его.

Мой вопрос: это безопасный способ?делать это?У меня есть обычный глобальный UserMutex для блокировки среза, только когда я добавляю к срезу ... Но при добавлении к срезу все существующие элементы перемещаются в память?

Что произойдет, если 1 поток добавляется к срезу, в то время как другой поток изменяет элемент?Может ли это произойти в приведенной выше настройке?

Могу ли я потенциально выделить достаточно большой фрагмент с помощью make (), чтобы любой метод append () не влиял на место в памяти?

1 Ответ

0 голосов
/ 05 июня 2018

Как вы уже заметили, это небезопасно, поскольку append может потребоваться выделить новый массив при превышении емкости, и это приведет к тому, что элементы будут скопированы в новый массив.

Однако,вы можете хранить указатели в вашем MyUsers срезе вместо значений:

var MyUsers []*User

Если вы сделаете это, то при выделении нового массива проблем не возникнет, так как указатели будут перемещаться, новсе еще указывая на те же базовые User структуры.

Кроме того, как отмечено в комментариях, было бы лучше использовать указатель на Mutex в структуре User на всякий случай:

Mutex *sync.RWMutex

Но было бы еще лучше, если бы вы разрабатывали свой код так, чтобы вы никогда не делали копию объекта User и всегда передавали указатели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...