Quelles sont les opérations atomiques, quels sont leurs types, et quand et comment est-il préférable de les utiliser?
sobes.tech IA
Réponse de l'IA
Les opérations atomiques sont des opérations sur la mémoire dont l'exécution garantit qu'elles se terminent complètement ou ne commencent pas du tout, et elles ne peuvent pas être interrompues par d'autres opérations concurrentes. Elles sont indivisibles et sûres pour les threads au niveau matériel.
Dans Go, le paquet sync/atomic fournit un ensemble de fonctions pour effectuer des opérations atomiques :
| Fonction | Description |
|---|---|
AddInt32 |
Ajoute de manière atomique une valeur à int32. |
AddInt64 |
Ajoute de manière atomique une valeur à int64. |
AddUint32 |
Ajoute de manière atomique une valeur à uint32. |
AddUint64 |
Ajoute de manière atomique une valeur à uint64. |
AddUintptr |
Ajoute de manière atomique une valeur à uintptr. |
CompareAndSwapInt32 |
Compare et échange (CAS) int32 de manière atomique. |
CompareAndSwapInt64 |
Compare et échange (CAS) int64 de manière atomique. |
CompareAndSwapUint32 |
Compare et échange (CAS) uint32. |
CompareAndSwapUint64 |
Compare et échange (CAS) uint64. |
CompareAndSwapUintptr |
Compare et échange (CAS) uintptr. |
CompareAndSwapPointer |
Compare et échange (CAS) unsafe.Pointer. |
LoadInt32 |
Charge de manière atomique la valeur de int32. |
LoadInt64 |
Charge de manière atomique la valeur de int64. |
LoadUint32 |
Charge de manière atomique la valeur de uint32. |
LoadUint64 |
Charge de manière atomique la valeur de uint64. |
LoadUintptr |
Charge de manière atomique la valeur de uintptr. |
LoadPointer |
Charge de manière atomique la valeur de unsafe.Pointer. |
StoreInt32 |
Stocke de manière atomique la valeur de int32. |
StoreInt64 |
Stocke de manière atomique la valeur de int64. |
StoreUint32 |
Stocke de manière atomique la valeur de uint32. |
StoreUint64 |
Stocke de manière atomique la valeur de uint64. |
StoreUintptr |
Stocke de manière atomique la valeur de uintptr. |
StorePointer |
Stocke de manière atomique la valeur de unsafe.Pointer. |
SwapInt32 |
Échange de manière atomique les valeurs de int32. |
SwapInt64 |
Échange de manière atomique les valeurs de int64. |
SwapUint32 |
Échange de manière atomique les valeurs de uint32. |
SwapUint64 |
Échange de manière atomique les valeurs de uint64. |
SwapUintptr |
Échange de manière atomique les valeurs de uintptr. |
SwapPointer |
Échange de manière atomique les valeurs de unsafe.Pointer. |
Il est préférable d'utiliser des opérations atomiques dans les cas où une synchronisation simple et de bas niveau est requise pour l'accès à des variables communes, comme des compteurs ou des drapeaux, sans utiliser de mutex. Elles offrent des coûts minimaux et de meilleures performances dans de tels scénarios.
Exemple d'utilisation d'un compteur atomique :
package main
import (
"fmt"
"sync"
"sync/atomic"
)
func main() {
var counter int64
var wg sync.WaitGroup
for i := 0; i < 100; i++ {
wg.Add(1)
go func() {
// Incrémentation atomique du compteur
atomic.AddInt64(&counter, 1)
wg.Done()
}()
}
wg.Wait()
// Chargement atomique de la valeur du compteur
fmt.Println("Compteur final :", atomic.LoadInt64(&counter))
}
Exemple d'utilisation de CompareAndSwap :
package main
import (
"fmt"
"sync/atomic"
)
func main() {
var value int32 = 10
// Tentative d'échange de la valeur si elle est actuellement 10, en 20
swapped := atomic.CompareAndSwapInt32(&value, 10, 20)
fmt.Println("Échange effectué :", swapped) // true
fmt.Println("Valeur :", value) // 20
// Tentative d'échange de la valeur si elle est actuellement 10, en 30
swapped = atomic.CompareAndSwapInt32(&value, 10, 30)
fmt.Println("Échange effectué :", swapped) // false
fmt.Println("Valeur :", value) // 20
}
Il est important de se rappeler que les opérations atomiques fonctionnent avec des types primitifs (entiers, pointeurs). Pour la synchronisation d'accès à des structures de données plus complexes ou l'exécution d'opérations bloquantes, des mutex ou d'autres mécanismes de synchronisation sont toujours nécessaires. Une utilisation excessive ou incorrecte des opérations atomiques peut entraîner des erreurs difficiles à détecter ou une baisse des performances.