Leser-Schreiber-Problem mit std::mutex und thread
-
hallo,
wir sollen das Leser-Schreiber-Problem umsetzen. Für den zusammenhang was das ist:Es existieren mehrere Prozesse, die gleichzeitig aus einer Datenbank lesen können. Weiterhin existieren mehrere Prozesse, die in die Datenbank schreiben.
Gleichzeitiges Lesen aus der Datenbank ist erlaubt. Möchte ein Prozess in die Datenbank schreiben, so wird allen anderen Prozessen der Zugriff untersagt.Wir haben dazu als lösung folgenden Pseudo-Code bekommen:
semaphore mutex=1; // Für den Zugriff auf 'rc' semaphore db = 1; // Zum Zugriff aud die Datenbank int rc = 0; // Anzahl lesebereiten Prozesse reader() { while (true) { // Endlosschleife down(mutex); // Exklusiven Zugirff auf 'rc' rc++; // ein Leser mehr if (rc == 1) // wenn es der erste Leser ist... down(db); // Exclusiven Zugriff für Leser up(mutex); // 'rc' freigeben read_database(); // Lesen! down(mutex); // Exklusiven Zugirff auf 'rc' rc--; // Ein Leser weniger if (rc == 0) // wenn es der letzte Leser war up(db); // DB freigeben up(mutex); // 'rc' freigeben use_data_read(); // unkritischer Bereich } } writer() { while (true) { // Endlosschleife think_up_data(); // unkritischer Bereich down(db); // Zugriff für Schreiber! write_database();// Schreiben! up(db); // DB freigeben } }
Auf C++11 bezogen wäre dann jeweils:
up(bla) = bla.unlock() und
down(bla) = bla.lock()Allerdings versteh ich nicht so recht den Pseudo-Code, bzw. allgemein das prinzip von std::mutex und std::thread. Was ich mir so denke:
- der erste Lesethread kommt in Zeile 8 an und blockiert mit down(mutex) alle Threads außer sich selbst (?)
- rc wird um eine hochgezählt
- da rc=1 ist, greift die if-Bedingung und der erste Lesethread führt diesmal ein down(db) aus, was wieder alle Threads blockiert obwohl sie schon vorher blockiert sind (?)
- Zeile 12, der erste lesethread macht ein up(mutex) und entblockiert alle Threads
- dann entblockiert er wieder alle Threads in Zeile 14????
- ...??
Ich versteh noch nichtmal wieso es überhaupt zwei Mutexe gibt (mutex und db siehe Zeile 1-2). Ich könnt mir vorstellen das wenn der erste Lesethread in Zeile 11 das down(db) ausführt, alle anderen Threads erst ab Zeile 11 blockiert werden und dadurch das rc um die Anzahl an Lesethreads hochgezhält wird und das sobald der erste Lesethread in Zeile 17 das up(db) ausführt die anderen Lesethreads entblockiert werden aber das ist auch nur ins blaue geraten.Ich glaub der hintergedanke von dem Pseudocode ist folgender:
Der erste Lesethread bewirkt ein down(db) in Zeile 11. Danach wird rc auf die Anzahl der Lesethreads hochgezählt und währenddessen können keine Schreibthreads starten weil sie durch das down(db) in Zeile 11 durch den ersten Lesethreads blockiert sind. Nun machen alle Lesethreads nacheinander ihr Zeugs mit der read_database() und die Variable rc wird immer weiter um eins kleiner. Das heißt der letzte Lesehread kommt in die if-Bedingung Zeile 16 rein und führt das up(db) aus, was wiederum dann die Schreibthreads entblockiert. Ich könnt mir denken das das so gemeint ist, aber wenn ich den Pseudocode Zeile für Zeile durchgeh versteh ich nicht wie das gehen soll.Hat irgendwer ne idee was ich da falsch denke?