BS_Praktikum4/ring_buffer.h
2025-06-03 01:40:44 +02:00

63 lines
2 KiB
C++

#pragma once
#include <array>
#include <mutex>
#include <condition_variable>
/**
* Thread-sicherer Ringpuffer mit fester Größe N
* Implementiert das Producer-Consumer-Pattern mit:
* - Mutex für exklusiven Zugriff
* - Condition Variable für blockierendes Lesen
* - Überschreibt älteste Daten bei vollem Puffer
*/
template <size_t N>
class RingBuffer {
std::array<int, N> data; // Speicher für die Elemente
size_t read = 0; // Lese-Position
size_t write = 0; // Schreib-Position
bool full = false; // Flag für vollen Puffer
std::mutex mtx; // Schützt alle Zugriffe
std::condition_variable cv; // Synchronisiert Leser
public:
/**
* Schreibt einen Wert in den Puffer
* @param value Der zu schreibende Wert
*
* Funktionsablauf:
* 1. Sperrt den Puffer mit Mutex
* 2. Schreibt Wert an aktueller Position
* 3. Überschreibt ältesten Wert wenn voll
* 4. Aktualisiert Schreib-Position
* 5. Benachrichtigt wartende Leser
*/
void push(int value) {
std::lock_guard<std::mutex> lock(mtx);
data[write] = value;
write = (write + 1) % N; // Ringverhalten
if (full) read = (read + 1) % N; // Überschreiben
full = (write == read); // Update Voll-Flag
cv.notify_one(); // Wecke einen Leser
}
/**
* Liest einen Wert aus dem Puffer (blockierend)
* @return Der gelesene Wert
*
* Funktionsablauf:
* 1. Sperrt den Puffer
* 2. Wartet bis Daten verfügbar
* 3. Liest Wert und aktualisiert Position
* 4. Gibt Wert zurück
*/
int pop() {
std::unique_lock<std::mutex> lock(mtx);
// Warte bis Daten da sind (verhindert Busy Waiting)
cv.wait(lock, [this]{ return full || write != read; });
int val = data[read];
read = (read + 1) % N; // Ringverhalten
full = false; // Nicht mehr voll
return val;
}
};