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?


Log in to reply