go / expert
Snippet
Sperrfreie Read-Copy-Update (RCU) Strategie mit atomic.Value
Das Read-Copy-Update (RCU) Muster ermöglicht sperrfreie Lesezugriffe für leseintensive Datenstrukturen durch den atomaren Austausch eines unveränderlichen Instanzzeigers via `atomic.Value`. Schreibzugriffe klonen die Struktur unter einem Mutex, was Schreibkonflikte verhindert und Lesern vollkommen sperrfreie Zugriffe garantiert.
snippet.go
go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package mainimport ("fmt""sync""sync/atomic")type MapConfig map[string]stringtype ConfigManager struct {current atomic.Value // Stores MapConfigwmu sync.Mutex // Serializes write updates}func NewConfigManager(initial MapConfig) *ConfigManager {cm := &ConfigManager{}cm.current.Store(initial)return cm}func (cm *ConfigManager) Get(key string) string {m := cm.current.Load().(MapConfig)return m[key]}func (cm *ConfigManager) Update(key, val string) {cm.wmu.Lock()defer cm.wmu.Unlock()// Read current map, clone it, and swap atomicallycurrMap := cm.current.Load().(MapConfig)newMap := make(MapConfig, len(currMap)+1)for k, v := range currMap {newMap[k] = v}newMap[key] = valcm.current.Store(newMap)}func main() {cm := NewConfigManager(MapConfig{"env": "prod"})cm.Update("debug", "false")fmt.Println(cm.Get("env"), cm.Get("debug"))}
Erklärung
1
m := cm.current.Load().(MapConfig)
Lädt atomar den aktuellen Snapshot ohne Sperren (Locks) zu halten oder Leser zu blockieren.
2
cm.current.Store(newMap)
Tauscht den neu modifizierten Snapshot atomar aus, sodass er sofort für alle zukünftigen Lesezugriffe verfügbar ist.