Das Leser-Schreiber-Problem leicht abgewandelt
-
Hallo zusammen!
Ich bin mir nicht ganz sicher ob ich hier richtig bin, ansonsten den Thread bitte verschieben.
Wie in der Überschrift bereits erwähnt, geht es um das sogenannte Leser-Schreiber Problem und dessen Lösung mithilfe von Semaphoren.
Das Problem dürfte vielen bereits bekannt sein, hier noch mal eine Zusammenfassung:
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.
Eine Lösung zu finden, die die Leseprozesse bevorzugt ist relativ einfach zu finden. Nun soll aber eine Lösung gefunden werden, die die schreibenden Prozesse bevorzugt.Dazu habe ich mir folgendes überlegt:
Wenn ein Prozess Schreibzugriff auf die Datenbank möchte, so muss dieser zunächst solange warten, bis alle lesenden Operationen abgeschlossen sind. Gleichzeitig muss verhindert werden, dass neue Prozesse Leserechte bekommen.
Wenn kein Leseprozess mehr auf die Datenbank zugreift, kann der Schreibprozess mit seiner Arbeit beginnen. Wenn weitere Schreibprozesse hinzukommen, dann sollen erst diese abgearbeitet werden. Erst wenn keine Schreibprozesse mehr Zugriff auf die Datenbank benötigen, sollen die Leseprozesse wieder aus der Datenbank lesen dürfen.
Ich habe zwar eine Lösung gefunden, jedoch bin ich mir erstens nicht zu 100% sicher ob diese überhaupt korrekt ist. Zweitens gehe ich davon aus, dass es noch eine elegantere Lösung als meine gibt. Vielleicht hat ja der ein oder andere eine Idee, die mir weiterhilft.
Nachfolgend die Lösung in Pseudo-Code...//down() und up() seinen atomare Operationen... typdef int semaphore; semaphore mutexR = 1; //Sichert den Zugriff auf die Variable rc semaphore mutexW = 1; //Sichert den Zugriff auf die Variable wc semaphore db = 1; //Sichert den exklusiven Zugriff auf die Datenbank semaphore bl = 1; //Schreibprozesse blockieren weitere Leseprozesse int rc = 0; //read count int wc = 0; //write count void reader() { //Leseprozess while(TRUE) { down(&bl); up(&bl); down(&mutexR); //exklusiver Zugriff auf rc if(++rc==1) down(&db); //Der erste Leser bewirkt einen //exklusiven Zugriff für Leseprozesse up(&mutexR); //exklusiven Zugriff auf rc frei read_from_database(); //Lese aus der Datenbank down(&mutexR); //exklusiver Zugriff auf rc if(--rc==0) up(&db); //Der letzte Leser gibt die Datenbank //wieder frei up(&mutexR); //exklusiven Zugriff auf rc frei work_with_data(); //nicht-kritischer Bereich } } void writer() { while(TRUE) { think_up_data(); //nicht-kritischer Bereich down(&mutexW); //exklusiver Zugriff auf wc if(++wc==1) down(&bl); //Der erste Schreiber bewirkt einen //exklusiven Zugriff für Schreibprozesse up(&mutexW); //exklusiven Zugriff auf wc frei down(&db); //Schreibprozesse benötigen exklusiven //Zugriff auf die Datenbank write_to_database(); //In die Datenbank schreiben up(&db); //exklusiven Zugriff auf Datenbank //freigeben down(&mutexW); //exklusiver Zugriff auf wc if(--wc==0) up(&bl); //Der letzte Schreiber erlaubt den //Leseprozessen wieder den Zugriff up(&mutexW); //exklusiven Zugriff auf wc frei } }
Gruß
Tobias
-
Wie wärs, wenn du mal vernünftig erläuterst, was du da überhaupt gemacht hast...