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...


Anmelden zum Antworten