当访问相同结构的不同字段但在单独的goroutine中需要sync.Mutex吗?

问题描述 投票:1回答:1

我有一个结构,其中包含几个简单字段(即:int,string和[] byte)。

我也有几个goroutine用来修改结构中的不同字段。但是每个goroutine都会修改自己的字段。

我没有注意到任何问题或比赛条件的提示。然后,我相当容易地将sync.Mutex添加到代码中,并且代码运行完全相同。

但是据我所读,似乎有人建议在这种情况下使用sync.Mutex。即使程序运行没有错误,还是需要它吗?

go goroutine
1个回答
0
投票

为了锁定的目的,将结构的每个字段都视为独立字段。给出:

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)
}()
© www.soinside.com 2019 - 2024. All rights reserved.