go / expert
Snippet
Sperrfreier konkurrenter Stapelspeicher mittels generischer atomarer Zeiger
Dieses Beispiel zeigt die Erstellung eines sperrfreien, threadsicheren Stapelspeichers unter Verwendung von generischen atomic.Pointer[T] aus Go 1.19+. Durch eine Compare-And-Swap (CAS) Wiederholungsschleife wird Mutex-Overhead vermieden und gleichzeitig Speicher-Sicherheit über konkurrierende Goroutinen hinweg gewährleistet.
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
package mainimport ("sync/atomic")type Node[T any] struct {Value Tnext *Node[T]}type LockFreeStack[T any] struct {head atomic.Pointer[Node[T]]}func (s *LockFreeStack[T]) Push(val T) {newHead := &Node[T]{Value: val}for {currHead := s.head.Load()newHead.next = currHeadif s.head.CompareAndSwap(currHead, newHead) {return}}}func (s *LockFreeStack[T]) Pop() (T, bool) {for {currHead := s.head.Load()if currHead == nil {var zero Treturn zero, false}nextHead := currHead.nextif s.head.CompareAndSwap(currHead, nextHead) {return currHead.Value, true}}}
Erklärung
1
type LockFreeStack[T any] struct { head atomic.Pointer[Node[T]] }
Definiert eine generische nebenläufige Stack-Struktur mit einem atomaren Zeiger auf den obersten Knoten.
2
if s.head.CompareAndSwap(currHead, newHead) { return }
Aktualisiert den Head-Zeiger atomar nur dann, wenn er mit dem erwarteten aktuellen Knoten übereinstimmt.