Saya memiliki struct yang memiliki beberapa bidang sederhana di dalamnya (yaitu: int, string, dan []byte).

Saya juga memiliki beberapa goroutine yang memodifikasi bidang yang berbeda dalam struct. Tetapi setiap goroutine memodifikasi bidangnya sendiri.

Saya belum melihat ada masalah atau petunjuk tentang kondisi balapan. Saya kemudian menambahkan sync.Mutex ke dalam kode dengan cukup mudah, dan kodenya berjalan persis sama.

Tetapi dari apa yang saya baca, tampaknya beberapa orang mungkin menyarankan untuk menggunakan sync.Mutex dalam situasi ini. Apakah diperlukan, meskipun program berjalan tanpa kesalahan?

0
user11924970 11 April 2020, 11:13

1 menjawab

Jawaban Terbaik

Perlakukan setiap bidang struct sebagai independen untuk tujuan penguncian. Diberikan:

type Foo struct {
    stringMap  map[string]string
    strings   []string
    numbers   []float64
}

Berikut ini aman:

foo := &Foo{}
/* ... */
go func() {
    foo.stringMap["foo"] = "bar"
}()
go func() {
    foo.strings[0] = "baz"
}()
go func() {
    fmt.Println(foo.numbers[0])
}()

Tapi ini tidak aman:

go func() {
    fmt.Println(foo.numbers[0])
}()
go func() {
    foo.numbers = append(foo.numbers, 123.456)
}()

Jadi, Anda biasanya menginginkan satu mutex untuk setiap bidang, atau setiap grup bidang yang dapat dimodifikasi bersama:

type Foo struct {
    stringMapMu sync.Mutex
    stringMap   map[string]string
    stringsMu   sync.Mutex
    strings     []string
    numbersMu   sync.Mutex
    numbers     []float64
}

Kemudian:

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)
}()
0
Flimzy 11 April 2020, 09:07