Maison > développement back-end > Golang > Pourquoi ce code Goroutine produit-il des résultats inattendus et comment éviter les courses aux données ?

Pourquoi ce code Goroutine produit-il des résultats inattendus et comment éviter les courses aux données ?

Linda Hamilton
Libérer: 2024-12-11 18:36:12
original
485 Les gens l'ont consulté

Why Does This Goroutine Code Produce Unexpected Results and How Can Data Races Be Avoided?

Course aux données dans le comportement de Goroutine

L'extrait de code fourni introduit un problème de course aux données qui peut conduire à des résultats imprévisibles. Le problème principal vient de la nature des Goroutines et de la manière dont la variable de plage est transmise à la fonction de la Goroutine.

La course aux données

Le code fourni utilise une plage boucle sur la tranche de données, et pour chaque itération, il démarre une nouvelle goroutine pour imprimer le champ de nom de la structure de champ. Cependant, au sein de chaque itération, la variable de plage v pointe vers la même structure de données sous-jacente dans la tranche de données, qui est une référence.

À mesure que la boucle progresse et que la variable v parcourt la tranche de données, sa valeur devient pointez vers l’élément suivant. Cela signifie qu'au moment où la fonction de la goroutine est exécutée, elle a la dernière valeur de v, qui est le dernier élément de la tranche.

Par conséquent, l'exécution des goroutines entraînera l'impression du champ de nom de seul le dernier élément, "trois", trois fois au lieu du "un", "deux", "trois" prévu dans n'importe quel order.

Solutions

Pour résoudre ce problème, plusieurs solutions sont disponibles :

  1. Créer une nouvelle variable :

    • Introduire une nouvelle variable v dans l'itération de boucle dont la portée est seulement à cette itération. Cela garantit que chaque goroutine a sa propre version unique de v qui pointe vers le bon élément dans la tranche.
  2. Utilisez une tranche de pointeurs :

    • Modifiez la tranche de données pour contenir des pointeurs vers les structures de champ au lieu de références directes. De cette façon, chaque itération de la boucle obtient un pointeur vers un élément spécifique, éliminant ainsi le problème de l'écrasement des variables.
  3. Utilisez l'adresse de l'élément Slice :

    • Prendre explicitement l'adresse de l'élément slice pendant la boucle range. Cela fournit à chaque goroutine l'adresse correcte de l'élément spécifique de la tranche.

Approches supplémentaires

  • Passer des arguments à une fonction anonyme : Utilisez une fonction anonyme dans la goroutine pour transmettre des variables de plage comme arguments. Cela garantit que chaque goroutine a accès à sa propre copie unique de la variable de plage.
  • Récepteur de pointeur : Le code utilise une méthode struct (field.print() ) avec un récepteur pointeur. Cette implémentation garantit généralement l'utilisation d'une tranche de pointeurs pour la tranche de données afin d'éviter le problème.

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!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal