Heim >Backend-Entwicklung >Golang >GO: Fehlende Synchronisierung

GO: Fehlende Synchronisierung

Linda Hamilton
Linda HamiltonOriginal
2024-11-30 01:10:11605Durchsuche

GO:lack of synchronization

var a string
var done bool

func setup() {
    a = "hello, world"
    done = true
}

func doprint() {
    if !done {
        once.Do(setup)
    }
    print(a)
}

func twoprint() {
    go doprint()
    go doprint()
}

Code-Analyse

Variablen:

  • a und b sind globale Variablen vom Typ int, die von allen Goroutinen gemeinsam genutzt werden.

Funktionen:

  • f():
    • Schreibt nacheinander in a und b (a = 1 und b = 2).
  • g():
  • Liest und druckt b gefolgt von a.

Parallelität in main():

  • Die Funktion f() wird als separate Goroutine mit go f() ausgeführt.
  • Die Funktion g() wird direkt in der Haupt-Goroutine ausgeführt.

Potenzielle Probleme:

  • Die Goroutine, die f() ausführt, und die Haupt-Goroutine, die g() ausführt, laufen gleichzeitig.
  • Die Schreibvorgänge in a und b in f() werden möglicherweise nicht abgeschlossen, bevor g() die Werte von a und b liest und druckt.
  • Dies führt zu einem Datenwettlauf, bei dem gleichzeitiger Zugriff (Schreiben in f() und Lesen in g()) auf den gemeinsam genutzten Speicher (a und b) ohne Synchronisierung erfolgt.

Mögliche Ergebnisse
Aufgrund der fehlenden Synchronisierung ist die Ausgabe des Programms nicht deterministisch. Hier sind die möglichen Szenarien:

Fall 1: g() wird ausgeführt, bevor f() a und b ändert:

  • Anfangswerte von a und b sind 0 (Standard für nicht initialisiertes int in Go).
0
0

oder

FALL 2: Wenn b = 2 vor g() abgeschlossen ist, a = 1 jedoch nicht, könnte die Ausgabe wie folgt lauten:

2
0

Wichtige Beobachtungen
Datenwettlauf: Der gleichzeitige Zugriff auf a und b ohne Synchronisierung führt zu einem Datenwettlauf. Dies macht das Verhalten des Programms undefiniert und unvorhersehbar

Den Code korrigieren

  1. Verwenden einer sync.WaitGroup: Stellen Sie sicher, dass f() abgeschlossen ist, bevor g() ausgeführt wird
var a, b int
var wg sync.WaitGroup

func f() {
    a = 1
    b = 2
    wg.Done()
}

func g() {
    print(b)
    print(a)
}

func main() {
    wg.Add(1)
    go f()
    wg.Wait()
    g()
}

  1. Verwenden von Kanälen: Signal, wenn f() fertig ist:
var a, b int

func f(done chan bool) {
    a = 1
    b = 2
    done <- true
}

func g() {
    print(b)
    print(a)
}

func main() {
    done := make(chan bool)
    go f(done)
    <-done
    g()
}

Hier wartet g(), bis f() ein Signal über den Fertig-Kanal sendet.

Das obige ist der detaillierte Inhalt vonGO: Fehlende Synchronisierung. 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