Maison >développement back-end >Golang >Comment éviter les courses aux données lors du lancement de Goroutines dans Go ?

Comment éviter les courses aux données lors du lancement de Goroutines dans Go ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-12-08 17:37:11180parcourir

How to Avoid Data Races When Launching Goroutines in Go?

Course de données dans une routine Go simultanée

Ce code démontre un problème de course aux données dans une routine Go simultanée :

package main

import (
    "fmt"
    "time"
)

type field struct {
    name string
}

func (p *field) print() {
    fmt.Println(p.name)
}

func main() {
    data := []field{{"one"}, {"two"}, {"three"}}
    for _, v := range data {
        go v.print()
    }
    <-time.After(1 * time.Second)
}

Problème :

Le code imprime "trois" trois fois au lieu de imprimer "un", "deux" et "trois" dans n'importe quel ordre. C'est parce qu'il y a une course aux données.

Explication :

Implicitement, le code prend l'adresse de la variable v lors de l'évaluation des arguments de la fonction goroutine. La fonction goroutine v.print() est équivalente à (&v).print(). La boucle change la valeur de v, et lorsque les goroutines s'exécutent, elles ont la dernière valeur de la boucle ("trois").

Corrections :

Il existe plusieurs façons de résoudre cette course aux données :

  • Créez une nouvelle variable dans le boucle :
for _, v := range data {
    v := v        // short variable declaration of new variable `v`.
    go v.print()
}
  • Utiliser une tranche de pointeurs :
data := []*field{{"one"}, {"two"}, {"three"}} // note '*'
for _, v := range data {
    go v.print()
}
  • Utiliser l'adresse de la tranche element :
data := []field{{"one"}, {"two"}, {"three"}} // note '*'
for i := range data {
    v := &data[i]
    go v.print()
}
  • Passez la variable de plage en argument à une fonction anonyme :
for _, v := range data {
  go func(v field) {
    v.print() // take address of argument v, not range variable v.
  }(v)
}

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!

Déclaration:
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