Go-Routine-Problem: Falsche Synchronisierung
Das Problem, auf das Sie in GoLang gestoßen sind, ist auf das Speichermodell zurückzuführen. Gemäß der Dokumentation können Lese- und Schreibvorgänge innerhalb einer einzelnen Goroutine neu angeordnet werden, solange dies keine Auswirkungen auf das Verhalten innerhalb dieser Goroutine hat.
Beachten Sie diesen Code:
var a, b int func f() { a = 1 b = 2 } func g() { print(b) print(a) } func main() { go f() g() }
Fällig Bei der Neuordnung des Speichermodells stellen Sie möglicherweise fest, dass g() 2 und dann 0 ausgibt. Auch wenn die Zuweisung von a vor der von b in f() steht, optimiert der Compiler möglicherweise die Code durch Zuweisen von b zuerst aus Effizienzgründen.
Innerhalb derselben Goroutine ist die Reihenfolge der Zuweisungen garantiert, da der Compiler sie nicht neu anordnen kann, wenn dies zu Problemen führen würde. Allerdings gibt es im gegebenen Beispiel keine Synchronisation zwischen den beiden Goroutinen. Daher muss der Compiler die möglichen Auswirkungen einer Neuordnung auf die andere Goroutine nicht berücksichtigen.
Wenn Sie eine Synchronisierung zwischen den Goroutinen einführen, z. B. eine WaitGroup oder einen Mutex, stellt der Compiler sicher, dass es keine Inkonsistenzen gibt am Synchronisationspunkt. In diesem Fall würden Sie erwarten, dass g() 2 und 1 ausgibt, da beide Zuweisungen vor den print()-Aufrufen abgeschlossen werden.
Das Verständnis dieses Aspekts des GoLang-Speichermodells ist entscheidend für das Schreiben gleichzeitiger Programme und das Vermeiden von gleichzeitigen Programmen mögliche Rennbedingungen oder andere Probleme, die aufgrund einer unerwarteten Neuordnung auftreten könnten.
Das obige ist der detaillierte Inhalt vonWarum druckt meine Go-Routine aufgrund der Neuordnung des Speichers unerwartete Werte?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!