Das Problem ist keine Optimierung durch den Go-Compiler, sondern eher ein Mangel an Synchronisierung. Auf die Zuweisung zu i folgt kein Synchronisationsereignis, daher kann nicht garantiert werden, dass sie von einer anderen Goroutine beobachtet wird. Tatsächlich könnte ein aggressiver Compiler die gesamte i-Anweisung löschen.
Das Go-Speichermodell
Das Go-Speichermodell gibt die Bedingungen an, unter denen eine Variable in einem gelesen wird Es kann garantiert werden, dass Goroutine Werte beobachtet, die durch Schreibvorgänge in dieselbe Variable in einer anderen Goroutine erzeugt werden.
Um den Zugriff zu serialisieren, schützen Sie die Daten mit Kanaloperationen oder anderen Synchronisierungsprimitiven wie denen in der sync- und sync/atomic-Pakete.
Wenn Sie den Rest dieses Dokuments lesen müssen, um das Verhalten Ihres Programms zu verstehen, sind Sie zu schlau. Seien Sie nicht schlau.
Synchronisation
Im folgenden Beispiel folgt auf die Zuweisung zu a kein Synchronisationsereignis, sodass dessen Einhaltung nicht garantiert ist von jeder anderen Goroutine. Tatsächlich könnte ein aggressiver Compiler die gesamte go-Anweisung löschen.
var a string
func hello() {
go func() { a = "hello" }()
print(a)
}
Das folgende Beispiel zeigt, wie der Zugriff auf i mithilfe eines sync.Mutex.
package main
import (
"sync"
"time"
)
func main() {
mx := new(sync.Mutex)
i := 1
go func() {
for {
mx.Lock()
i
mx.Unlock()
}
}()
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