Thread-Synchronisation via Konstruktor/Destruktor



  • Hi Leutz!

    Hab mal eine generelle Frage bezüglich der Thread-Synchronisation und Klassen in C++:
    Wenn ich eine Klasse schreibe, die in ihrem Konstruktor automatisch eine Lock-Methode eines Thread-Synchronisations-Objekts aufruft, sodass durch das Erstellen des Objekts der Klasse automatisch ein bestimmter Vorgang synchronisiert wird und im Destruktor der Klasse die entsprechende Unlock-Methode implementiert ist...ist dieses Prinzip sicher/okay ?

    Vielen Dank schonmal!

    Grüße, Steve 😉 .


  • Mod

    Sicher in welcher Hinsicht?



  • Wenn die Unlock Methode garantiert nie fehlschlägt schon.



  • Hi, danke für Eure Antworten!

    camper schrieb:

    Sicher in welcher Hinsicht?

    In Bezug auf die Sychronisation. Ist das damit dann wirklich sicher ?

    hustbaer schrieb:

    Wenn die Unlock Methode garantiert nie fehlschlägt schon.

    Ähm was meinst Du mit 'fehlschlägt' ? Könntest Du mit dazu ein Beispiel geben?

    Also ich habe beispielsweise folgenden Code (Windows-Code):

    #include <windows.h>
    
    class CUserLock
    {
       private:
         CRITICAL_SECTION m_cs;
         bool m_fInit, m_fLock;
       public:
         CUserLock  (void) : m_fLock(false), m_fInit(false) {}
         ~CUserLock (void) { Release(); }
    
         void Initialize (void) { if(!m_fInit){ InitializeCriticalSection(&m_cs); m_fInit = true; ) }
         void Release    (void) { Unlock(); if(m_fInit){ DeleteCriticalSection(&m_cs); m_fInit = false; } }
         void Lock       (void) { if(m_fInit && !m_fLock){ EnterCriticalSection(&m_cs); m_fLock = true; } }
         void Unlock     (void) { if(m_fInit && m_fLock){ LeaveCriticalSection(&m_cs); m_fLock = false; } }
    };
    
    class CAutoLock
    {
       private:
         CUserLock* m_pLock;
       public:
         CAutoLock(CUserLock& cLockObj) { m_pLock = &cLockObj; m_pLock->Initialize(); m_pLock->Lock();}
         ~CAutoLock(CUserLock& cLockObj) { m_pLock = &cLockObj; m_pLock->Initialize(); m_pLock->Unlock();}
    };
    

    Verwendeung wäre dann:

    // zum Beispiel global:
    CUserLock g_cDataLock;
    // ...
    void func(void)
    {
       CAutoLock(g_cDataLock);
       // Hier der sichere (?!) Code ;) .
    }
    

    Wär das so in jeder Situation in Ordnung (Falls nicht, wie sollte/müsste der Code denn korrekterweise aussehen 🤡 ) ? Danke schonmal für Eure Tipps 👍 !



  • Ups, sorry die Klasse CAutoLock muss natürlich so aussehen, sorry, vertippt:

    class CAutoLock
    {
       private:
         CUserLock* m_pLock;
       public:
         CAutoLock(CUserLock& cLockObj) { m_pLock->Initialize(); m_pLock->Lock(); }
         ~CAutoLock(CUserLock& cLockObj) { m_pLock->Unlock(); m_pLock->Release(); }
    };
    


  • Das Initialize und Release sollte nicht in CAutoLock sondern in den Konstruktor/Destruktor von CUserLock.



  • Hm okay, und sonst, ist der Code in jedem Fall sicher zum sychronisieren zu verwenden ?



  • Ähm was meinst Du mit 'fehlschlägt' ? Könntest Du mit dazu ein Beispiel geben

    // nicht ok, unlock kann fehlschlagen:
    void MyLock::Unlock()
    {
        if (!ReleaseMutex(m_mutexHandle))
            throw std::runtime_error("...");
    }
    
    // ok, kann nicht fehlschlagen:
    void MyLock::Unlock()
    {
        if (!ReleaseMutex(m_mutexHandle))
            terminate();
    }
    

Anmelden zum Antworten