Le problème n'est pas une optimisation par le compilateur Go, mais plutôt un manque de synchronisation. L'affectation à i n'est suivie d'aucun événement de synchronisation, il n'est donc pas garanti qu'elle soit observée par une autre goroutine. En fait, un compilateur agressif pourrait supprimer l'intégralité de l'instruction i.
Le modèle de mémoire Go
Le modèle de mémoire Go spécifie les conditions dans lesquelles les lectures d'une variable dans un goroutine peut être assuré d'observer les valeurs produites par les écritures dans la même variable dans une goroutine différente.
Pour sérialiser l'accès, protégez les données avec des opérations de canal ou d'autres primitives de synchronisation telles que celles de sync et packages sync/atomic.
Si vous devez lire le reste de ce document pour comprendre le comportement de votre programme, vous êtes trop intelligent. Ne soyez pas malin.
Synchronisation
Dans l'exemple suivant, l'affectation à a n'est suivie d'aucun événement de synchronisation, il n'est donc pas garanti qu'elle soit observée par n'importe quel autre goroutine. En fait, un compilateur agressif pourrait supprimer l'intégralité de l'instruction go.
var a string
func hello() {
go func() { a = "hello" }()
print(a)
}
L'exemple suivant montre comment sérialiser l'accès à i à l'aide d'un sync.Mutex.
package main
import (
"sync"
"time"
)
func main() {
mx := new(sync.Mutex)
i := 1
go func() {
for {
mx.Lock()
i
mx.Unlock()
}
}()
Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.
Copyright© 2022 湘ICP备2022001581号-3