I see in Essential Go that using a mutex within a struct is not too straight-forward. To quote from the Mutex Gotchas page:
Don’t copy mutexes
A copy of
sync.Mutex
variable starts with the same state as original mutex but it is not the same mutex.It’s almost always a mistake to copy a
sync.Mutex
e.g. by passing it to another function or embedding it in a struct and making a copy of that struct.If you want to share a mutex variable, pass it as a pointer
*sync.Mutex
.
I'm not quite sure I fully understand exactly what's written. I looked here but still wasn't totally clear.
Taking the Essential Go example of a Set, should I be using the mutex like this:
type StringSet struct {
m map[string]struct{}
mu sync.RWMutex
}
or like this?
type StringSet struct {
m map[string]struct{}
mu *sync.RWMutex
}
I tried both with the Delete() function within the example and they both work in the Playground.
// Delete removes a string from the set
func (s *StringSet) Delete(str string) {
s.mu.Lock()
defer s.mu.Unlock()
delete(s.m, str)
}
There will obviously be several instances of a 'Set', and hence each instance should have its own mutex. In such a case, is it preferable to use the mutex or a pointer to the mutex?