Datenwettlauf in der gleichzeitigen Go-Routine
Dieser Code zeigt ein Datenwettlaufproblem in einer gleichzeitigen Go-Routine:
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) }
Problem:
Der Code druckt „drei“ dreimal statt Drucken von „eins“, „zwei“ und „drei“ in beliebiger Reihenfolge. Dies liegt daran, dass es einen Datenwettlauf gibt.
Erklärung:
Implizit verwendet der Code die Adresse der Variablen v, wenn er Argumente für die Goroutine-Funktion auswertet. Die Goroutine-Funktion v.print() entspricht (&v).print(). Die Schleife ändert den Wert von v, und wenn die Goroutinen ausgeführt werden, haben sie zufällig den letzten Wert der Schleife („drei“).
Korrekturen:
Es gibt mehrere Möglichkeiten, diesen Datenwettlauf zu beheben:
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) }
Das obige ist der detaillierte Inhalt vonWie vermeide ich Datenrennen beim Starten von Goroutinen in Go?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!