Fonction d'ajout : non thread-safe pour un accès simultané
Lors de l'utilisation simultanée de goroutines pour ajouter des éléments à une tranche dans une boucle for, des anomalies dans les données peut survenir. Des données manquantes ou vides peuvent apparaître dans la tranche résultante, indiquant des courses de données potentielles.
Cela se produit car dans Go, aucune valeur n'est intrinsèquement sûre pour la lecture et l'écriture simultanées. Les tranches, représentées par des en-têtes de tranche, ne font pas exception. Le code fourni présente des courses de données dues à un accès simultané :
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()
Pour vérifier la présence de courses de données, exécutez la commande suivante :
go run -race play.go
La sortie vous alertera des courses de données :
WARNING: DATA RACE ...
Résoudre les problèmes de concurrence
Pour résoudre ce problème, protégez l'accès en écriture au destSlice en utilisant un 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()
Vous pouvez également envisager d'utiliser un canal pour gérer les ajouts de manière asynchrone :
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()
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!