- Я вижу, как некоторые люди используют несколько мьютексов в одной структуре. Это необходимо? Или мы можем просто поставить туда один-единственный замок? пример:
type Session struct {
// some other irrelevant code
pingLock sync.Mutex
// some other irrelevant code
streamLock sync.Mutex
// some other irrelevant code
shutdownLock sync.Mutex
}
- Если структура содержит другую структуру, а дочерняя структура содержит карту или срез, куда следует поместить мьютекс, родительскую структуру или дочернюю структуру?
- Почему mutex.Lock() не работает в моем коде? Каждый раз, когда я запускаю гоночный тест, он показывает, что гонки есть.
Сначала я пытался решить первые две проблемы, поэтому написал демонстрационный код, чтобы протестировать его. Я пытался использовать блокировку в дочерней структуре, а затем родительскую структуру для блокировки состояния, но ни один из них не работал. Гоночный тест продолжает говорить, что есть состояние гонки. Я пробовал и t.Lock()
, и 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"])