Heim >Backend-Entwicklung >Golang >Warum führt dieser Goroutine-Code zu unerwarteten Ergebnissen und wie können Datenrennen vermieden werden?

Warum führt dieser Goroutine-Code zu unerwarteten Ergebnissen und wie können Datenrennen vermieden werden?

Linda Hamilton
Linda HamiltonOriginal
2024-12-11 18:36:12486Durchsuche

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

Datenwettlauf im Goroutine-Verhalten

Das bereitgestellte Code-Snippet führt zu einem Datenwettlaufproblem, das zu unvorhersehbaren Ergebnissen führen kann. Das Kernproblem ergibt sich aus der Natur von Goroutinen und der Art und Weise, wie die Bereichsvariable an die Funktion der Goroutine übergeben wird.

Der Datenwettlauf

Der bereitgestellte Code verwendet einen Bereich Schleife über den Datenausschnitt und startet für jede Iteration eine neue Goroutine, um das Namensfeld der Feldstruktur zu drucken. Innerhalb jeder Iteration zeigt die Bereichsvariable v jedoch auf dieselbe zugrunde liegende Datenstruktur im Datenausschnitt, die eine Referenz ist.

Während die Schleife fortschreitet und die Variable v den Datenausschnitt durchläuft, ändert sich ihr Wert in auf das nächste Element zeigen. Dies bedeutet, dass die Funktion der Goroutine zum Zeitpunkt der Ausführung den letzten Wert von v hat, was das letzte Element im Slice ist.

Daher führt die Ausführung der Goroutinen dazu, dass das Namensfeld von gedruckt wird nur das letzte Element, „drei“, dreimal anstelle des beabsichtigten „eins“, „zwei“, „drei“ in jedem bestellen.

Lösungen

Um dieses Problem zu beheben, stehen mehrere Lösungen zur Verfügung:

  1. Erstellen Sie eine neue Variable :

    • Fügen Sie eine neue Variable v innerhalb der Schleifeniteration ein, die einen Gültigkeitsbereich hat nur zu dieser Iteration. Dadurch wird sichergestellt, dass jede Goroutine ihre eigene einzigartige Version von v hat, die auf das richtige Element im Slice zeigt.
  2. Verwenden Sie ein Slice von Zeigern:

    • Ändern Sie das Datensegment, um Zeiger auf die Feldstrukturen anstelle direkter Referenzen zu enthalten. Auf diese Weise erhält jede Iteration der Schleife einen Zeiger auf ein bestimmtes Element, wodurch das Problem des Überschreibens von Variablen vermieden wird.
  3. Verwenden Sie die Adresse des Slice-Elements:

    • Übernehmen Sie während der Bereichsschleife explizit die Adresse des Slice-Elements. Dadurch erhält jede Goroutine die richtige Adresse für das spezifische Element im Slice.

Zusätzliche Ansätze

  • Argumente an anonyme Funktion übergeben:Verwenden Sie eine anonyme Funktion innerhalb der Goroutine, um Bereichsvariablen als Argumente zu übergeben. Dadurch wird sichergestellt, dass jede Goroutine Zugriff auf ihre eigene eindeutige Kopie der Bereichsvariablen hat.
  • Zeigerempfänger: Der Code verwendet eine Strukturmethode (field.print() ) mit einem Zeigerempfänger. Diese Implementierung erfordert normalerweise die Verwendung eines Zeigersegments für das Datensegment, um das Problem zu vermeiden.

Das obige ist der detaillierte Inhalt vonWarum führt dieser Goroutine-Code zu unerwarteten Ergebnissen und wie können Datenrennen vermieden werden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
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