Fonction d'ajout : non thread-safe pour l'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 données courses :
WARNING: DATA RACE ...
Résolution des problèmes de concurrence
Pour résoudre ce problème, protégez l'accès en écriture à 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 de manière asynchrone les ajouts :
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
Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.
Copyright© 2022 湘ICP备2022001581号-3