Heim > Artikel > Backend-Entwicklung > Warum ist die Funktion „Anhängen' für den gleichzeitigen Zugriff in Go nicht threadsicher?
Anhängefunktion: Nicht Thread-sicher für gleichzeitigen Zugriff
Bei der gleichzeitigen Verwendung von Goroutinen zum Anhängen von Elementen an ein Slice innerhalb einer for-Schleife treten Anomalien auf in Daten entstehen können. Fehlende oder leere Daten können im resultierenden Slice 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 Datenrennen aufmerksam :
WARNING: DATA RACE ...
Parallelitätsprobleme lösen
An Um dieses Problem zu beheben, schützen Sie den Schreibzugriff auf das destSlice, indem Sie einen sync.Mutex verwenden:
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()
Alternativ können Sie einen Kanal verwenden, um die Anhänge asynchron zu verarbeiten:
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 <- tmpObj }(myObject) } go func() { for { tmpObj := <-appendChan destSlice = append(destSlice, tmpObj) } }() wg.Wait()
Das obige ist der detaillierte Inhalt vonWarum ist die Funktion „Anhängen' für den gleichzeitigen Zugriff in Go nicht threadsicher?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!