- I see some people out some mutexes within a single struct. Is it necessary? Or can we simply put one single lock there? example:
type Session struct {
// some other irrelevant code
pingLock sync.Mutex
// some other irrelevant code
streamLock sync.Mutex
// some other irrelevant code
shutdownLock sync.Mutex
}
- If a struct contains another struct, and the child struct contains a map or a slice, where should I put the mutex, the parent struct or the child struct?
- Why is the mutex.Lock() not working in my code? Every time I run race test it shows there are races.
At first I was trying to solve the first two problems so I wrote some demo code to test it out. I tried to use the lock within the child struct ,then parent struct to lock the state, but none of them worked. The race test keeps saying there is race condition.
I've tried both t.Lock()
and t.data.Lock()
.
type Test struct {
name string
data Data
sync.RWMutex //Should I put it here?
}
type Data struct {
d map[string]int
sync.RWMutex // Should I put it here?
}
func (t *Test) add(key string) {
t.data.Lock()
defer t.data.Unlock()
t.data.d[key] += 1
}
func (t *Test) read() {
for {
t.data.Lock()
_= t.data.d["test"]
t.data.Unlock()
}
}
func main() {
t := &Test{}
t.name = "oops"
t.data = Data{}
t.data.d = make(map[string]int)
t.data.d["test"] = 1
for i := 0; i <= 10; i++ {
go func(t *Test) {
t.add("test")
}(t)
go func(t *Test) {
t.read()
}(t)
}
time.Sleep(time.Second * 3)
fmt.Printf("result is %v", t.data.d["test"])