Когда вы используете карту в программе с параллельным доступом, существует ли необходимость использовать мьютекс в функциях для , чтобы читать значения?Карта с одновременным доступом
ответ
Несколько читателей, не писатели не в порядке:
https://groups.google.com/d/msg/golang-nuts/HpLWnGTp-n8/hyUYmnWJqiQJ
Один писатель, нет читателей не в порядке. (Карты не будут прока иначе.)
В противном случае, если есть хотя бы один писатель и по крайней мере, еще ни писателю или читателя один, то всех читателей и писателей должны использовать синхронизацию, чтобы получить доступ к карте , Мьютекс отлично подходит для этого.
Я ответил на ваш вопрос в this Reddit нити несколько дней назад:
В Go, карты не потокобезопасные. Кроме того, данные требуют блокировки даже для чтения , если, например, может быть другой горутин, который является , записывая одни и те же данные (одновременно).
Судя по пояснениям в комментариях, что есть функции setter, ответ на ваш вопрос да, вы должны будете защитить свои чтения с помощью мьютекса; вы можете использовать RWMutex. В качестве примера вы можете посмотреть на source реализации структуры данных таблицы (использует карту за кулисами), которую я написал (фактически тот, что связан в потоке reddit).
Это обычно расточительно использовать полную блокировку чтения-записи для ресурса, так быстро доступ как карту. – rmmh
Можете ли вы немного рассказать? Что было бы лучше подходит? –
Блокировки RW хороши для ресурсов с большим количеством споров, но у них больше накладных расходов, чем мьютексы. Map get/sets достаточно быстр, чтобы программа, вероятно, не имела достаточного количества аргументов, чтобы сделать более сложную блокировку более эффективной, чем простой мьютекс. – rmmh
Вы можете использовать concurrent-map, чтобы справиться с болями параллелизма.
// Create a new map.
map := cmap.NewConcurrentMap()
// Add item to map, adds "bar" under key "foo"
map.Add("foo", "bar")
// Retrieve item from map.
tmp, ok := map.Get("foo")
// Checks if item exists
if ok == true {
// Map stores items as interface{}, hence we'll have to cast.
bar := tmp.(string)
}
// Removes item under key "foo"
map.Remove("foo")
. Вот почему я не могу серьезно относиться к понятию «не нужны дженерики ». – Lucretiel
Понятие не в том, что Go «не нужны дженерики», но «в настоящее время нет чистого способа реализации дженериков, нам нужно подумать об этом еще немного». C++, например, генерирует код для всех возможных сочетаний типов, которые используются, что увеличивает время компиляции и размеры исполняемого файла необоснованной суммой. – Alexander
Если у вас только один писатель, то вы, вероятно, можете уйти от использования атомного значения. Заимствован из https://golang.org/pkg/sync/atomic/#example_Value_readMostly следующим образом (оригинал использует блокировки для защиты письма, поэтому поддерживает несколько авторов)
type Map map[string]string
var m Value
m.Store(make(Map))
read := func(key string) (val string) { // read from multiple go routines
m1 := m.Load().(Map)
return m1[key]
}
insert := func(key, val string) { // update from one go routine
m1 := m.Load().(Map) // load current value of the data structure
m2 := make(Map) // create a new map
for k, v := range m1 {
m2[k] = v // copy all data from the current object to the new one
}
m2[key] = val // do the update that we need (can delete/add/change)
m.Store(m2) // atomically replace the current object with the new one
// At this point all new readers start working with the new version.
// The old version will be garbage collected once the existing readers
// (if any) are done with it.
}
sync.Map
слился Пойти мастер по состоянию на 27 апреля, 2017.
Это параллельная карта мы все ждали.
Ницца. Обратите внимание, что новый тип sync.Map предназначен для карт только для приложений (по этой причине он не использует очертание ключей, а это означает, что если ваша карта имеет много оттока, она, скорее всего, будет отставать от карт с осколками в соответствии с мой ответ выше). – orcaman
@orcaman, что вы имеете в виду по картам только для приложения? – OmarIlias
@OmarIlias Я имею в виду случаи, когда вы в основном устанавливаете новые значения (без редактирования или удаления существующих значений). См. Это: https://github.com/golang/go/issues/20360 – orcaman
Почему не использовал модель Go параллелизм вместо этого, не существует простой пример ...
type DataManager struct {
/** This contain connection to know dataStore **/
m_dataStores map[string]DataStore
/** That channel is use to access the dataStores map **/
m_dataStoreChan chan map[string]interface{}
}
func newDataManager() *DataManager {
dataManager := new(DataManager)
dataManager.m_dataStores = make(map[string]DataStore)
dataManager.m_dataStoreChan = make(chan map[string]interface{}, 0)
// Concurrency...
go func() {
for {
select {
case op := <-dataManager.m_dataStoreChan:
if op["op"] == "getDataStore" {
storeId := op["storeId"].(string)
op["store"].(chan DataStore) <- dataManager.m_dataStores[storeId]
} else if op["op"] == "getDataStores" {
stores := make([]DataStore, 0)
for _, store := range dataManager.m_dataStores {
stores = append(stores, store)
}
op["stores"].(chan []DataStore) <- stores
} else if op["op"] == "setDataStore" {
store := op["store"].(DataStore)
dataManager.m_dataStores[store.GetId()] = store
} else if op["op"] == "removeDataStore" {
storeId := op["storeId"].(string)
delete(dataManager.m_dataStores, storeId)
}
}
}
}()
return dataManager
}
/**
* Access Map functions...
*/
func (this *DataManager) getDataStore(id string) DataStore {
arguments := make(map[string]interface{})
arguments["op"] = "getDataStore"
arguments["storeId"] = id
result := make(chan DataStore)
arguments["store"] = result
this.m_dataStoreChan <- arguments
return <-result
}
func (this *DataManager) getDataStores() []DataStore {
arguments := make(map[string]interface{})
arguments["op"] = "getDataStores"
result := make(chan []DataStore)
arguments["stores"] = result
this.m_dataStoreChan <- arguments
return <-result
}
func (this *DataManager) setDataStore(store DataStore) {
arguments := make(map[string]interface{})
arguments["op"] = "setDataStore"
arguments["store"] = store
this.m_dataStoreChan <- arguments
}
func (this *DataManager) removeDataStore(id string) {
arguments := make(map[string]interface{})
arguments["storeId"] = id
arguments["op"] = "removeDataStore"
this.m_dataStoreChan <- arguments
}
- 1. Является ли это потокобезопасным с одновременным доступом?
- 2. Ошибки Azure CloudAppendBlob с одновременным доступом
- 3. Ограничить пользователей одновременным доступом к страницам
- 4. Совместимость с JPA-кешем с одновременным доступом к базе данных
- 5. Вручную создать идентификатор таблицы PostgreSQL с одновременным доступом
- 6. Проблемы с одновременным доступом к sqlitedatabase на Android?
- 7. Непоследовательное поведение с одновременным доступом postgresql через node.js
- 8. Карта с безразличным доступом к ключу
- 9. Управление одновременным доступом к базе данных Apache Derby
- 10. Управление одновременным одновременным выполнением параллельных задач
- 11. Работа с одновременным доступом к XML-файлу с использованием java-сервера
- 12. Хэш/карта с быстрым доступом к n наивысшим значениям
- 13. Что делать, чтобы обновлять данные с одновременным доступом к sqlite 3
- 14. Актеры Scala с одновременным доступом к общему кешу объектов, scala.concurrent.Lock, реакция и прием
- 15. Блокировка подсказок для таблицы с одновременным доступом для чтения и записи
- 16. Неблокирующее сообщение с одновременным сообщением
- 17. JSON-файл с одновременным чтением
- 18. Отключить клавиатуру с одновременным представлением
- 19. Использование урожайности с одновременным сбором
- 20. В чем разница между одновременным выполнением и одновременным выполнением?
- 21. В чем разница между одновременным соединением и одновременным запросом?
- 22. Как управлять одновременным одновременным просмотром содержимого двух сборщиков?
- 23. Проблемы с одновременным с Hibernate Criteria + join
- 24. Исключение с одновременным изменением с объектами
- 25. Является ли этот класс/метод C# безопасным потоком и одновременным доступом безопасным?
- 26. Как сделать UITableView одновременным?
- 27. Как управлять одновременным доступом ввода/вывода к XML-файлу из нескольких экземпляров EXE, используя Delphi.
- 28. Весенняя сессия с одновременным обновлением сессий jdbc
- 29. Проблемы с одновременным выпуском веб-запросов
- 30. Проблемы с одновременным вызовом двух функций
Если это строго только для чтения карты, мьютекс не требуется. – jimt
Я был не очень ясен, так как будут функции для установки и получения значений. –