Maison >développement back-end >Golang >Comment utiliser les verrous dans Go ?
En programmation concurrente, le verrouillage est un mécanisme utilisé pour protéger les ressources partagées. Dans le langage Go, les verrous sont l'un des outils importants pour parvenir à la concurrence. Il garantit que lorsque plusieurs coroutines accèdent simultanément aux ressources partagées, une seule coroutine peut lire ou modifier ces ressources. Cet article présentera l'utilisation des verrous en langage Go pour aider les lecteurs à mieux comprendre la programmation simultanée.
Mutual Exclusion Lock est le mécanisme de verrouillage le plus couramment utilisé dans le langage Go. Cela garantit qu’une seule coroutine peut accéder à la section critique en même temps. En termes simples, un verrou mutex garantit qu'une seule coroutine peut y accéder en même temps en encapsulant la ressource partagée dans la section critique du verrouillage.
Utiliser les verrous mutex en langage Go est très simple. Nous pouvons utiliser le type Mutex dans le package de synchronisation pour créer un verrou mutex :
import "sync" var mutex = &sync.Mutex{}
Après cela, à l'emplacement où les ressources partagées doivent être protégées, nous pouvons utiliser le code suivant pour obtenir le verrou :
mutex.Lock() defer mutex.Unlock()# 🎜🎜#Il convient de noter que les verrous mutex ne prennent pas en charge la réentrée. Si une coroutine a déjà acquis le verrou, tenter à nouveau d’acquérir le verrou entraînera un blocage. Par conséquent, nous utilisons généralement l'instruction defer pour libérer automatiquement le verrou à la fin de la coroutine. Ce qui suit est un exemple d'utilisation d'un mutex :
import ( "fmt" "sync" ) var count = 0 var mutex = &sync.Mutex{} func increment(wg *sync.WaitGroup) { mutex.Lock() defer mutex.Unlock() count++ wg.Done() } func main() { var wg sync.WaitGroup for i := 0; i < 1000; i++ { wg.Add(1) go increment(&wg) } wg.Wait() fmt.Println("Count:", count) }Dans cet exemple, nous utilisons un mutex pour protéger un compteur. 1 000 coroutines exécutent la fonction d'incrémentation en même temps, en ajoutant 1 au compteur à chaque fois. Grâce à l'utilisation de verrous mutex, le programme peut afficher correctement la valeur finale du compteur.
import "sync" var rwlock = &sync.RWMutex{}Les méthodes d'acquisition du verrouillage en lecture et du verrouillage en écriture sont différentes. Voici quelques utilisations courantes :
import ( "fmt" "sync" ) var count = 0 var rwlock = &sync.RWMutex{} func increment(wg *sync.WaitGroup) { rwlock.Lock() defer rwlock.Unlock() count++ wg.Done() } func read(wg *sync.WaitGroup) { rwlock.RLock() defer rwlock.RUnlock() fmt.Println("Count:", count) wg.Done() } func main() { var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go increment(&wg) } wg.Wait() for i := 0; i < 5; i++ { wg.Add(1) go read(&wg) } wg.Wait() }
Dans cet exemple, nous avons ouvert simultanément 10 coroutines pour écrire des données sur le compteur et 5 coroutines pour lire les données du compteur. En utilisant des verrous en lecture-écriture, les programmes peuvent lire les ressources partagées de manière efficace tout en garantissant l'atomicité des opérations d'écriture.
Opérations atomiquesLe langage Go a plusieurs fonctions d'opération atomique intégrées, vous pouvez vous référer à la documentation officielle. Voici deux fonctions d’opération atomique couramment utilisées : atomic.Add et atomic.Load.
atomic.Add : effectue une opération d'addition atomique sur un entier.import ( "fmt" "sync/atomic" "time" ) var count int32 = 0 func increment(wg *sync.WaitGroup) { defer wg.Done() atomic.AddInt32(&count, 1) } func printCount() { fmt.Println("Count: ", atomic.LoadInt32(&count)) } func main() { var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go increment(&wg) } wg.Wait() printCount() time.Sleep(time.Second) for i := 0; i < 3; i++ { wg.Add(1) go increment(&wg) } wg.Wait() printCount() }
Dans cet exemple, nous utilisons la fonction atomic.Add pour effectuer des opérations d'addition atomique sur le compteur, et l'atomique .Load fonction atomiquement Lire la valeur du compteur manuellement. En utilisant des opérations atomiques, nous pouvons éviter la surcharge des verrous et obtenir une programmation simultanée plus efficace.
SummaryCe 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!