Warum ist das Anhängen an ein Slice in gleichzeitigen Goroutinen nicht threadsicher?

Linda Hamilton
Freigeben: 2024-11-10 00:49:02
Original
759 Leute haben es durchsucht

Why is Appending to a Slice in Concurrent Goroutines Not Thread-Safe?

Gleichzeitige Slices: Anhängen nicht threadsicher

Frage:

Bedenken Sie den folgenden Code das an ein Slice angehängt wird und mehrere Goroutinen innerhalb eines for verwendet Schleife:

destSlice := make([]myClass, 0)

var wg sync.WaitGroup
for _, myObject := range sourceSlice {
    wg.Add(1)
    go func(closureMyObject myClass) {
        defer wg.Done()
        var tmpObj myClass
        tmpObj.AttributeName = closureMyObject.AttributeName
        destSlice = append(destSlice, tmpObj)
    }(myObject)
}
wg.Wait()
Nach dem Login kopieren

Gelegentlich erzeugt dieser Code fehlende oder leere Daten in destSlice oder schließt nicht alle Elemente aus sourceSlice ein. Warum könnte das passieren?

Antwort:

In Go sind alle Werte anfällig für Datenwettläufe, wenn sie gleichzeitigen Lese-/Schreibvorgängen unterliegen, einschließlich Slices. Dies liegt an der Art und Weise, wie Slice-Header (die Informationen über die Kapazität und Länge des Slice enthalten) implementiert werden.

Das Ausführen des Codes mit der Flagge -race bestätigt das Vorhandensein von Datenrennen:

go run -race play.go
Nach dem Login kopieren

Lösung:

Um Datenwettläufe zu vermeiden und gleichzeitige Sicherheit beim Anhängen an einen Slice zu gewährleisten, ein Synchronisationsprimitiv B. ein sync.Mutex, sollte verwendet werden, um das Schreiben des destSlice-Werts zu schützen:

var (
    mu        = &sync.Mutex{}
    destSlice = make([]myClass, 0)
)

var wg sync.WaitGroup
for _, myObject := range sourceSlice {
    wg.Add(1)
    go func(closureMyObject myClass) {
        defer wg.Done()
        var tmpObj myClass
        tmpObj.AttributeName = closureMyObject.AttributeName
        mu.Lock()
        destSlice = append(destSlice, tmpObj)
        mu.Unlock()
    }(myObject)
}
wg.Wait()
Nach dem Login kopieren

Alternativ können Sie Kanäle verwenden, um den gleichzeitigen Anhängeprozess zu erleichtern.

Das obige ist der detaillierte Inhalt vonWarum ist das Anhängen an ein Slice in gleichzeitigen Goroutinen nicht threadsicher?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage