Append-Funktion: Nicht Thread-sicher für gleichzeitigen Zugriff
Bei der gleichzeitigen Verwendung von Goroutinen zum Anhängen von Elementen an einen Slice innerhalb einer for-Schleife treten Anomalien auf in Daten entstehen können. Im resultierenden Slice können fehlende oder leere Daten erscheinen, was auf mögliche Datenrennen hinweist.
Dies liegt daran, dass in Go kein Wert von Natur aus sicher für gleichzeitiges Lesen und Schreiben ist. Slices, die durch Slice-Header dargestellt werden, bilden keine Ausnahme. Der bereitgestellte Code weist Datenrennen aufgrund des gleichzeitigen Zugriffs auf:
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()
Um das Vorhandensein von Datenrennen zu überprüfen, führen Sie den folgenden Befehl aus:
go run -race play.go
Die Ausgabe macht Sie auf Daten aufmerksam Rennen:
WARNING: DATA RACE ...
Lösen von Parallelitätsproblemen
Um dieses Problem zu beheben, schützen Sie den Schreibzugriff auf das destSlice durch den Einsatz eines sync.Mutex:
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()
Erwägen Sie alternativ die Verwendung eines Kanals zur asynchronen Verarbeitung der Anhänge:
var ( appendChan = make(chan myClass) 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 appendChan
Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.
Copyright© 2022 湘ICP备2022001581号-3