CriticalSection, blos wie richtig verwenden?



  • Hallo,

    Ich habe mehrere threads die auf die elemente in der Doc-Klasse zugreifen und will das mit einer CriticalSection koordinieren.
    Also habe ich ein CCriticalsection Objekt in der Doc-Klasse erstellt und rufe in jeder Funktion der Doc-Klasse am anfang Lock() und am Ende Unlock() auf.
    Ich dachte, meine Doc-Klasse sei nun "threadsicher", bekomme aber Abstürze!

    class myprogDoc{
       ...
       CCriticalSection m_CS;
       ...
    }
    
    void myprogDoc::test(){
        m_CS.Lock();
    
         ....//greife auf Daten zu
    
        m_CS.Unlock();
    }
    
    UINT __cdecl theApp::ThreadFunc(LPVOID pParam){
        ....
        pDoc->test();
        ....
    }
    

    Wenn ich es so mache stürzt mein programm aber (bisher) nicht ab:

    void myprogDoc::Lock(){
       m_CS.Lock();
    }
    void myprogDoc::Unlock(){
       m_CS.Unlock();
    }
    
    UINT __cdecl theApp::ThreadFunc(LPVOID pParam){
        ....
        pDoc->Lock();
        pDoc->test();
        pDoc->Unlock();
        ....
    }
    

    Ist denn die untere variante so richtig?
    Und warum klappt die erste nicht, bzw. warum kann ich die CS nicht in der funktion in der Doc-Klasse Locken und Unlocken 😮



  • Ich verwende die CriticalSections normalerweise zusammen mit CSingleLock:

    void myprogDoc::test()
    {
      CSingleLock cLock(&m_CS,TRUE);
      ... greife auf Daten zu
    }
    

    Ansonsten: Wie äußern sich denn die "Abstürze"?



  • Wenn das Lock/Unlock in myprogDoc::test nicht funktioniert hast du irgendwo anders ein Problem.
    Davon abgesehen würde ich auch zur Verwendung von CSingleLock raten - ist viel einfacher und exception-safe.



  • Ich würde das auch wie CStoll verwenden. Du kannst CSingleLock auch in einen eigenen Stackrahmen packen. Sobald die schließende Klammer durchlaufen wird, wird das CSingleLock-Object vernichtet und der Lock aufgehoben.

    void myprogDoc::test()
    {
       tue hier was
          {//ab hier ist Lock aktiv  
             CSingleLock cLock(&m_CS,TRUE);
             ... greife auf Daten zu
          }//ab hier ist lock wieder weg
       tue hier noch was
    }
    

Anmelden zum Antworten