Monitor klasse Synchronisierung der Threads läuft nur bedingt



  • Hi

    ich hoffe ihr könnte mir bei meinem Problem weiterhelfen, da ich schon seit Wochen verzweifelt nach einer Lösung suche und
    wäre für jeden Vorschlag dankbar.

    Ich versuche seit geraumer Zeit zwei Thread, ein lese und ein schreib Thread, zu synchronisieren. Dabei greifen beide Threads
    auf ein Lesepuffer (8 Listobjekte, die jeweils ein array<Byte> beinhalten). Zur Synchronisierung benutze ich die Monitor Methode
    aus dem Namensraum System::Threading. Die eigenart dieser Klasse erlaubt es nur OBJEKTE zu sperren, was ja eigentlich sehr sinnvoll
    ist, jedoch kann man keine LISTELEMENTE einzeln sperren. Versucht man bspw. mit Monitor::Enter(Liste[0]) Listelemente zu sperren
    , wird im folgenden das ganze LISTOBJEKT gesperrt und nicht das Listelement mit dem INDEX 0.
    Daher musste ich bei der Implementierung mit der Monitor Methode mehrere Listobjekte erzeugen, die ich dann seperat sperren und
    entsperren konnte. Die auswahl der Listobjekte habe ich dann mit Switch Case Anweisung realisiert.

    try
    {
    for(int nIndexIn=0;nIndexIn<8;nIndexIn++)
    { 
    		switch(nIndexIn)
    		{
    			case 0: bendwrite=false;
    			while(Monitor::TryEnter(abyte1Ringpuffer,1)!=true||bIsReadyRead1==true)
    			{
    				//breadenable=true; //-- Lese Thread wird gestartet --
    				rtb2->AppendText("Thread 1,1 geblockt\n"+umlauf+"\n");
    			}
    			abyte1Ringpuffer[0]=(USB->readBlockPipeOut(nEpadd,nBlocksize,nTransfer));
    			Monitor::Exit(abyte1Ringpuffer);
    			bIsReadyRead1=true;
    
    			//rtb2->AppendText("----Thread 1,1 nicht geblockt----\n");
    
    			break;
    
    			case 1: //Siehe oben
    		}
    }
    .........usw.
    
    finally
    {
    
    	if(Monitor::TryEnter(abyte1Ringpuffer)==true)
    	{
    		Thread::CurrentThread->Sleep(10);
    		Monitor::Exit(abyte1Ringpuffer);
    	}
    	else
    	{
    		rtb2->AppendText("RP 1 geblockt\n");
    	}
    
    	if(Monitor::TryEnter(abyte2Ringpuffer)==true)
    	{
    		Thread::CurrentThread->Sleep(10);
    		Monitor::Exit(abyte2Ringpuffer);
    	}
    	else
    	{
    		rtb2->AppendText("RP 2 geblockt\n");
    	}
    	......... usw.
    
    }
    

    analog dazu habe ich ein lese Thread geschrieben, der ebenfalls den Ringpuffer durchläuft und entsprechend die Boolen setzt bei
    erfolgreichem einlesen, so dass die Threads synchronisiert ablaufen sollte. Versucht der Lese Thread den Schreibe thread zu überholen, wird der
    Lese thread geblockt und warte solange bis der Schreib Thread das Listobjekt wieder freigibt.
    Das Programm funktioniert auch.... nur wenn ich die Abort Methode aufrufe und beide Threads abbreche und anschließend die Threads
    erneut starte, wird angezeigt, dass die Listobjekte weiterhin gesperrt sind.
    Obwohl nach der Finally Implementierung bei einer AbortException aufjedenfall die Listobjekte entsperrt werden sollte.

    Meine Frage dazu ist: warum sind die Objekte denn immernoch gesperrt, obwohl durch Finally eigentlich die Entsperrung GEWÄHRLEISTET
    ist ???

    Ich hoffe dass ich mein Problem verständlich gemacht habe, falls was doch noch unverständlich sein sollte kurze Rückmeldung.

    Danke



  • Monitore haben reference counting. Du brauchst die gleiche Anzahl von Exit wie Enter.
    In deinem Code ist diese Bedingung nicht erfüllt.

    WW


Anmelden zum Antworten