l'éditeur php Baicao est là pour vous présenter une technique très utile, qui consiste à verrouiller la carte pour un accès simultané. Cette technique peut aider les développeurs à éviter les conflits et les erreurs de données lors de l'accès simultané à la carte. En utilisant un mécanisme de verrouillage, les développeurs peuvent garantir que chaque demande est effectuée dans l'ordre et qu'aucun encombrement de données ne se produit. Ceci est très important pour développer des opérations cartographiques, en particulier lorsque plusieurs utilisateurs accèdent à la carte en même temps. Voyons comment mettre en œuvre cette technique !
J'ai une carte : map[string]map[string]*Struct et je dois la lire/écrire dans plusieurs routines Go.
Quelle est la meilleure façon d’y parvenir ? Mutex ou RW Mutex ? Et où le placer ?
Si j'utilise RWMutex, dois-je verrouiller ou RLock avant d'effectuer des opérations impliquant la lecture et l'écriture ?
J'ai essayé d'utiliser rwmutex dans la carte racine, mais je ne sais pas si c'est la meilleure façon de résoudre ce problème.
J'ai aussi essayé de "verrouiller" avant de lire et d'écrire, mais parfois j'ai des paniques "écritures simultanées".
Vous pouvez utiliser RWLock. Si l'opération implique l'écriture (qu'il s'agisse de lecture ou d'écriture uniquement), vous devez utiliser Lock, si elle implique uniquement la lecture, RLock/RUnlock.
Lock peut également être considéré comme un cadenas exclusif. RLock, en revanche, est non exclusif. Un RLock peut être acquis même si le RWMutex est verrouillé en lecture, mais l'exécution de la goroutine sera bloquée si la ressource est verrouillée exclusivement par la méthode Lock :
a blocked Lock call excludes new readers from acquiring the lock
D'un autre côté, la méthode Lock bloque l'exécution de la goroutine jusqu'à ce que tous les lecteurs et rédacteurs déverrouillent la ressource (en utilisant la méthode RUnlock/Unlock). Lock est exclusif car une seule goroutine peut accéder à la ressource (en lecture ou en écriture) jusqu'à ce que la méthode Unlock soit appelée.
Méthode typique :
package main import ( "fmt" "sync" ) type SomeStruct struct { someInfo string } type ConcurrentStruct struct { mu sync.RWMutex data map[string]map[string]*SomeStruct } func New() *ConcurrentStruct { return &ConcurrentStruct{ data: make(map[string]map[string]*SomeStruct), } } func (cs *ConcurrentStruct) Set(key1, key2 string, val SomeStruct) { cs.mu.Lock() defer cs.mu.Unlock() if _, ok := cs.data[key1]; !ok { cs.data[key1] = make(map[string]*SomeStruct) } cs.data[key1][key2] = &val } func (cs *ConcurrentStruct) Get(key1, key2 string) (val *SomeStruct, ok bool) { cs.mu.RLock() defer cs.mu.RUnlock() if _, ok := cs.data[key1]; ok { val, ok := cs.data[key1][key2] return val, ok } return nil, false } func main() { cs := New() cs.Set("a", "b", SomeStruct{"Hello, World!"}) if _, ok := cs.Get("a", "c"); !ok { fmt.Printf("key1=a, key2=c, not found\n") } if s, ok := cs.Get("a", "b"); ok { fmt.Printf("key1=a, key2=b, found: %v\n", s) } }
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!