In diesem Codeausschnitt wird eine Goroutine gestartet und erhöht wiederholt die Variable i:
package main
import "time"
func main() {
i := 1
go func() {
for {
i
}
}()
Die Ausgabe ist jedoch immer 1. Dieses Verhalten kann dem Go-Speichermodell und der spezifischen Implementierung dieses Codes zugeschrieben werden.
Das Go-Speichermodell
Das Das Go-Speichermodell definiert die Bedingungen, unter denen garantiert werden kann, dass Lesevorgänge einer Variablen in einer Goroutine Werte beobachten, die durch Schreibvorgänge in dieselbe Variable in einer anderen Goroutine erzeugt werden. Es betont die Bedeutung der Synchronisierung für den gleichzeitigen Zugriff auf gemeinsam genutzte Daten.
Auslassen der Synchronisierung
Im angegebenen Code:
- Die Zuweisung an i (d. h. i) Es folgt kein Synchronisierungsereignis, was darauf hinweist, dass Änderungen möglicherweise nicht sofort für andere Goroutinen sichtbar sind.
- Der Compiler kann diese Schleifenoptimierung optimieren, indem er sie auf einen No-Op vereinfacht.
Optimierung durch den Compiler
Ein aggressiver Compiler könnte die i-Anweisung löschen und die Goroutine effektiv reduzieren auf:
for {}
Beispiel mit Synchronisierung
Um zu zeigen, dass das Problem auf die mangelnde Synchronisierung zurückzuführen ist, betrachten Sie den folgenden Code:
package main
import (
"sync"
"time"
)
func main() {
mx := new(sync.Mutex)
i := 1
go func() {
for {
mx.Lock()
i
mx.Unlock()
}
}()
In diesem Fall ist die Ausgabe nicht mehr 1, sondern wie erwartet eine große Zahl. Der sync.Mutex sorgt für Synchronisierung und stellt sicher, dass beide Goroutinen auf kontrollierte Weise auf i zugreifen, wodurch die Goroutine i inkrementieren kann und die Änderungen für die Hauptroutine sichtbar werden.
Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.
Copyright© 2022 湘ICP备2022001581号-3