Heim > Backend-Entwicklung > Golang > Wie vermeide ich Datenrennen beim Starten von Goroutinen in Go?

Wie vermeide ich Datenrennen beim Starten von Goroutinen in Go?

Mary-Kate Olsen
Freigeben: 2024-12-08 17:37:11
Original
210 Leute haben es durchsucht

How to Avoid Data Races When Launching Goroutines in Go?

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)
}
Nach dem Login kopieren

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:

  • Erstellen Sie eine neue Variable innerhalb der Schleife:
for _, v := range data {
    v := v        // short variable declaration of new variable `v`.
    go v.print()
}
Nach dem Login kopieren
  • Verwenden Sie ein Stück Zeiger:
data := []*field{{"one"}, {"two"}, {"three"}} // note '*'
for _, v := range data {
    go v.print()
}
Nach dem Login kopieren
  • Verwenden Sie die Adresse des Slice Element:
data := []field{{"one"}, {"two"}, {"three"}} // note '*'
for i := range data {
    v := &data[i]
    go v.print()
}
Nach dem Login kopieren
  • Übergeben Sie die Bereichsvariable als Argument an eine anonyme Funktion:
for _, v := range data {
  go func(v field) {
    v.print() // take address of argument v, not range variable v.
  }(v)
}
Nach dem Login kopieren

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!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage