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 :
for _, v := range data { v := v // short variable declaration of new variable `v`. go v.print() }
data := []*field{{"one"}, {"two"}, {"three"}} // note '*' for _, v := range data { go v.print() }
data := []field{{"one"}, {"two"}, {"three"}} // note '*' for i := range data { v := &data[i] go v.print() }
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!