75 lines
2.1 KiB
C
75 lines
2.1 KiB
C
|
|
#pragma once
|
||
|
|
#include <mutex>
|
||
|
|
#include <condition_variable>
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Implementiert das Reader-Writer Problem mit:
|
||
|
|
* - Mehrere gleichzeitige Leser
|
||
|
|
* - Exklusiver Zugriff für Schreiber
|
||
|
|
* - Verhindert Writer-Starvation
|
||
|
|
*/
|
||
|
|
class AnalysisModel {
|
||
|
|
int value = 0; // Das geteilte Analysemodell (vereinfacht)
|
||
|
|
int reader_count = 0; // Zählt aktive Leser
|
||
|
|
|
||
|
|
// Synchronisationsprimitive
|
||
|
|
std::mutex model_mutex; // Schützt Schreibzugriffe (exklusiv)
|
||
|
|
std::mutex count_mutex; // Schützt Leserzähler
|
||
|
|
std::condition_variable no_writer; // Garantiert Fairness
|
||
|
|
|
||
|
|
public:
|
||
|
|
/**
|
||
|
|
* Lesender Zugriff
|
||
|
|
* @return Aktueller Wert des Modells
|
||
|
|
*
|
||
|
|
* Funktionsweise:
|
||
|
|
* 1. Sperrt count_mutex und inkrementiert reader_count
|
||
|
|
* 2. Erster Leser sperrt model_mutex (blockiert Writer)
|
||
|
|
* 3. Entsperrt count_mutex während des Lesens
|
||
|
|
* 4. Liest Wert
|
||
|
|
* 5. Sperrt count_mutex zum Dekrementieren
|
||
|
|
* 6. Letzter Leser entsperrt model_mutex und benachrichtigt Writer
|
||
|
|
*/
|
||
|
|
int read() {
|
||
|
|
std::unique_lock<std::mutex> count_lock(count_mutex);
|
||
|
|
reader_count++;
|
||
|
|
|
||
|
|
// Erster Leser sperrt für Writer
|
||
|
|
if(reader_count == 1) {
|
||
|
|
model_mutex.lock();
|
||
|
|
}
|
||
|
|
count_lock.unlock();
|
||
|
|
|
||
|
|
// Kritischer Abschnitt (Lesen, kann parallel erfolgen)
|
||
|
|
int result = value;
|
||
|
|
|
||
|
|
count_lock.lock();
|
||
|
|
reader_count--;
|
||
|
|
// Letzter Leser gibt für Writer frei
|
||
|
|
if(reader_count == 0) {
|
||
|
|
model_mutex.unlock();
|
||
|
|
no_writer.notify_one();
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Schreibender Zugriff
|
||
|
|
* @param new_value Neuer Wert für das Modell
|
||
|
|
*
|
||
|
|
* Funktionsweise:
|
||
|
|
* 1. Sperrt model_mutex (exklusiver Zugriff)
|
||
|
|
* 2. Schreibt neuen Wert
|
||
|
|
* 3. Wartet bis alle Leser fertig sind (Starvation Prevention)
|
||
|
|
*/
|
||
|
|
void write(int new_value) {
|
||
|
|
std::unique_lock<std::mutex> lock(model_mutex);
|
||
|
|
value = new_value;
|
||
|
|
|
||
|
|
// Verhindert Writer-Starvation
|
||
|
|
no_writer.wait(lock, [this]() {
|
||
|
|
return reader_count == 0;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
};
|