Zugriff auf CList synchronisieren mit Threads



  • Hallo, ich habe einen Programm der Protokolldaten in einer Liste zwischen speichert. ein zweiter Thread liest die Daten aus der Liste aus und speichert sie in der Datenbank.
    ich brauche eine Liste von Listen
    typedef CList<cTimerObj,cTimerObj&> cTodiProtEntrie
    CList<cTodiProtEntrie*, cTodiProtEntrie*>

    class CProtEntriesList: public CList<cTodiProtEntrie*, cTodiProtEntrie*>
    {
    private:
    	CCriticalSection m_CritSection;
    public:
    
    	CProtEntriesList(){};
    
    	//fügt ein neues Element am ende der Liste
    	int AddToEnd(cTodiProtEntrie* newTimerObj)
    	{
    		POSITION pos = NULL;
    		m_CritSection.Lock();
    		pos = AddTail(newTimerObj);
    		m_CritSection.Unlock();
    		if(pos == NULL)
    			return -1;
    		else
    			return 0;
    	}
    
    	// das Element aus dem Anfang der Liste holen
    	cTodiProtEntrie* GetFromFront()
    	{
    		m_CritSection.Lock();
    		return IsEmpty() ? NULL : RemoveHead();//error C2558: class 'cTimerObj' : Kein Kopierkonstruktor verfuegbar
    		m_CritSection.Unlock();
    	}
    };
    

    den Zugriff auf die Liste habe ich mit CritSection synchronisiert direkt in der einfügen und lesen-funktion.
    habe ich das richtig gemacht?



  • cTodiProtEntrie* GetFromFront()
        {
            m_CritSection.Lock();
            return IsEmpty() ? NULL : RemoveHead();//error C2558: class 'cTimerObj' : Kein Kopierkonstruktor verfuegbar
            m_CritSection.Unlock();
        }
    

    Unlock wird nicht aufgerufen.
    Es bleibt ewig gelockt.

    Benutze doch sowas wie ein ScopedCrtiticalSection.
    Beim Konstruktor wird EnterCriticalSection(..) aufgerufen und beim Destruktor wird LeaveCriticalSection(..) aufgerufen. Das ist auch Exception Safe.



  • Danke simon für den Hinweis
    ich habe jetzt die Funktion so umgeschrieben:

    // das Element aus dem Anfang der Liste holen
    	cTodiProtEntrie* GetFromFront()
    	{
    		cTodiProtEntrie* ProtEntrie;
    		m_CritSection.Lock();
    		if(IsEmpty())
    			ProtEntrie = NULL;
    		else
    			ProtEntrie = RemoveHead();
    		m_CritSection.Unlock();
    		return ProtEntrie; 		
    	}
    

  • Mod

    BTW: Viel einfacher ist es das ganze so zu machen, dann wird es auch Excpetion sicher!

    {
     // Start locked section
     CSingleLock lock(&m_CritSection,TRUE);
      ...
     // Destructor will Unlock
    }
    


  • Sofern ich das richtig verstehe arbeitest du mit 2 Threads die ein und den selben Oberflächen Thread bearbeiten.

    Mein Verständnis war bis jetzt das man niemals aus einem zweiten Thread irgendwas mit der Benutzeroberfläche aus einem anderen Thread machen sollte. Aber vielleicht wolltest du grade dies mit deinen Locks umgehen?. Warum keine Messages oder eine eigne threadsichere Ereigniswarteliste?

    Stell dir mal vor wenn während du dich noch in deinem Timer Thread in der Ausführung der GetFromFront Funktion befindest Paint etc aufruft.. dann ist der Zustand nicht wirklich definiert. Du müsstest alle Funktionen mit deiner Lock überladen um sicherzustellen das während einer Änderung der andere Thread nicht zeichnet etc, aber selbst damit bin ich mir nicht sicher ob das ideal ist.



  • Hallo DaRpH,
    mein Threads ist kein obefläche-Thread sondern ein worker-Thread der im hintegrund laufen soll.
    das programm(Hauptthread in diesem Fall) soll mit hilfe einer funktion die Protokolldaten in einer Liste (statt direkt wie bisher in db) speichern. die funktion geht zurück und im hintegrund soll ein Thread gestartet um die Daten aus der Liste in der DB zu speichern.
    beide Hauptprogram und der Thread können auf der Liste gleichzeitig zugreifen. deswegen muss ich das ganze synchronisieren um inkonsistenz zu vermeiden.

    zu Martin Richter:
    danke. ich werde mir CSingleLock anschauen


Log in to reply