我有一个结构,其中包含几个简单字段(即:int,string和[] byte)。
我也有几个goroutine用来修改结构中的不同字段。但是每个goroutine都会修改自己的字段。
我没有注意到任何问题或比赛条件的提示。然后,我相当容易地将sync.Mutex添加到代码中,并且代码运行完全相同。
但是据我所读,似乎有人建议在这种情况下使用sync.Mutex。即使程序运行没有错误,还是需要它吗?
为了锁定的目的,将结构的每个字段都视为独立字段。给出:
type Foo struct {
stringMap map[string]string
strings []string
numbers []float64
}
以下内容是安全的:
foo := &Foo{}
/* ... */
go func() {
foo.stringMap["foo"] = "bar"
}()
go func() {
foo.strings[0] = "baz"
}()
go func() {
fmt.Println(foo.numbers[0])
}()
但是这不安全:
go func() {
fmt.Println(foo.numbers[0])
}()
go func() {
foo.numbers = append(foo.numbers, 123.456)
}()
因此,通常,您希望每个字段或每个字段组都可以使用一个互斥体,可以一起修改:
type Foo struct {
stringMapMu sync.Mutex
stringMap map[string]string
stringsMu sync.Mutex
strings []string
numbersMu sync.Mutex
numbers []float64
}
然后:
go func() {
foo.numbersMu.Lock()
defer foo.numbersMu.Unlock()
fmt.Println(foo.numbers[0])
}()
go func() {
foo.numbersMu.Lock()
defer foo.numbersMu.Unlock()
foo.numbers = append(foo.numbers, 123.456)
}()