Как заблокировать карту и исправить данные гонки - PullRequest
0 голосов
/ 05 января 2019

Я пытаюсь решить ВНИМАНИЕ: ГОНКА ДАННЫХ вот код:

package models

import (
  "sync"
  "time"
)
type Stats struct {
    sync.Mutex
    request map[int64]int
}

func (s *Stats) PutRequest() {
  s.Lock()
  s.request[time.Now().Unix()]++
  s.Unlock()
}
func (s *Stats) GetRequests() map[int64]int {
    s.Lock()
    m := s.request
    s.Unlock()
    return m
 }
var Requests = Stats{
    sync.Mutex{},
    make(map[int64]int),
}

Если я изменю запрос поля Stats на целое число, то everithing работает нормально, но не с картой. Как правильно заблокировать карту в Go?

Ответы [ 2 ]

0 голосов
/ 06 января 2019

Использовать sync.RWMutex

func (s *Stats) PutRequest(ut int64) {
  s.Lock()
  defer s.Unlock()
  s.request[ut]++
}

func (s *Stats)  GetRequests() map[int64]int {
    s.RLock()
    defer s.RUnlock()
    m := make(map[int64]int, len(s.request))
    for k, v := range s.request {
        m[k] = v
    }
    return m
}

Следующий пример канала может быть интересен в этом случае. пример - отслеживание состояния goroutines

В любом случае вам необходимо скопировать карту перед возвратом.

0 голосов
/ 06 января 2019

GetRequests возвращает ссылку на карту, поэтому, если другой код вызывает функцию и выполняет возврат на карте возврата без получения блокировки, тогда вводится гонка данных

...