R
R
Roman Mirilaczvili2020-08-18 16:31:23
go
Roman Mirilaczvili, 2020-08-18 16:31:23

What is the best way to avoid race conditions in struct methods in Go? Are there any practices?

I wrote this code. Certainly not thread-safe.

...
func (s *Scanner) incrExtCount(ext string) {
  _, found := s.stats.extFreq[ext]
  if found {
    s.stats.extFreq[ext]++
  } else {
    s.stats.extFreq[ext] = 1
  }
}

func (s *Scanner) addPath(path string) {
  s.stats.recentPaths.PushFront(path)
  s.stats.pathsNum++
  if s.stats.pathsNum > MaxPaths {
    s.stats.recentPaths.Remove(s.stats.recentPaths.Back())
  }
}
...

I can wrap every data read and write operation (line of code) in a mutex lock/unlock, but is that correct?
What type of mutex should be used in this case?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
U
uvelichitel, 2020-08-18
@2ord

type GuardedScanner struct{
    s *Scanner
    *sync.Mutex //Поскольку метод всегда пишет заморачиваться с RWMutex смысла не вижу
}
func (gs *GuardedScanner) addPath(path string) {
    gs.Lock()
    gs.s.addPath(path)
    gs.Unlock()
}
//В первом методе можно обойтись sync/atomic
...
type stats struct{
...
    extFreq map[string]*uint64
...
}
func (gs *GuardedScanner) incrExtCount(ext string) {
  _, found := s.stats.extFreq[ext]
  if found {
    atomic.AddUint64(gs.stats.extFreq[ext], 1)
  } else {
    atomic.StoreUint64(gs.stats.extFreq[ext], 1)
  }
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question