cpp / expert
Snippet
Lock-freier atomarer Ringpuffer
Ein hochperformanter Ringpuffer, der std::array und atomare Operationen für thread-sicheren Zugriff ohne Mutexe nutzt. Er verwendet Memory-Ordering, um die Datenkonsistenz zwischen Producer- und Consumer-Threads zu gewährleisten.
snippet.cpp
cpp
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
#include <array>#include <atomic>#include <optional>template <typename T, std::size_t N>class AtomicRingBuffer {std::array<T, N> buffer;std::atomic<std::size_t> head{0};std::atomic<std::size_t> tail{0};public:bool push(const T& value) {std::size_t h = head.load(std::memory_order_relaxed);std::size_t next_h = (h + 1) % N;if (next_h == tail.load(std::memory_order_acquire)) return false;buffer[h] = value;head.store(next_h, std::memory_order_release);return true;}std::optional<T> pop() {std::size_t t = tail.load(std::memory_order_relaxed);if (t == head.load(std::memory_order_acquire)) return std::nullopt;T value = buffer[t];tail.store((t + 1) % N, std::memory_order_release);return value;}};
Erklärung
1
std::array<T, N> buffer;
Verwendet ein fest dimensioniertes Array auf dem Stack für maximale Cache-Effizienz und Vorhersehbarkeit.
2
std::atomic<std::size_t> head{0};
Atomare Indizes verhindern Race-Conditions während gleichzeitiger Push- und Pop-Operationen.
3
std::memory_order_release
Stellt sicher, dass der Datenschreibvorgang für andere Threads sichtbar ist, bevor die Indexaktualisierung veröffentlicht wird.