Thread-Safety in Go : une alternative à la synchronisation
Dans le domaine de la programmation, la sécurité des threads garantit qu'une variable est accessible simultanément par plusieurs threads sans provoquer d'incohérence des données. Dans Go, le concept de synchronisation, tel qu'on le voit en Java avec le mot-clé synchronisé, n'est pas explicitement appliqué mais plutôt abordé à travers différents mécanismes.
Go prône l'approche du « communiquer en partageant » plutôt que du « partage de mémoire en communicant." Ce paradigme encourage l'échange d'informations entre les goroutines via des canaux au lieu d'accéder directement aux variables partagées.
Mutex : une solution classique
Cependant, dans les scénarios où le verrouillage et le partage d'une variable sont inévitable, Go fournit des mutex. Prenons l'exemple suivant :
import ( "sync" ) var ( mu sync.Mutex protectMe int ) func getMe() int { mu.Lock() me := protectMe mu.Unlock() return me } func setMe(me int) { mu.Lock() protectMe = me mu.Unlock() }
Dans ce code, la variable ProtectMe est protégée à l'aide d'un mutex nommé mu. Les fonctions getMe et setMe utilisent ce mutex pour garantir un accès simultané sécurisé à ProtectMe.
Améliorations et alternatives
Bien que la solution ci-dessus soit fonctionnelle, il existe plusieurs façons d'améliorer it :
Une implémentation améliorée ressemblerait à ceci :
type Me struct { sync.RWMutex me int } func (m *Me) Get() int { m.RLock() defer m.RUnlock() return m.me } func (m *Me) Set(me int) { m.Lock() m.me = me m.Unlock() } var me = &Me{}
Atomic Opérations
Pour protéger des entiers uniques, Go fournit des opérations atomiques via le package sync/atomic. Considérez le code suivant :
import "sync/atomic" var protectMe int32 func getMe() int32 { return atomic.LoadInt32(&protectMe) } func setMe(me int32) { atomic.StoreInt32(&protectMe, me) }
Les opérations atomiques garantissent un accès sécurisé aux threads à des valeurs uniques et peuvent offrir de meilleures performances que les mutex dans certaines situations.
Communiquer par partage
Comme mentionné précédemment, la communication via les canaux est encouragée dans Go. Imaginez que vous ayez deux goroutines : une définissant un état et une autre le lisant. Au lieu d'utiliser une variable partagée et d'en synchroniser l'accès, vous pouvez utiliser un canal pour envoyer l'état du setter au lecteur :
import "sync" var c chan int func init() { c = make(chan int) } func getMe() int { return <-c } func setMe(me int) { c <- me }
Cette approche élimine le besoin de variables partagées et de synchronisation, simplifiant ainsi le code et le rendant intrinsèquement sûr pour un accès simultané.
Ressources supplémentaires
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!