critical section problem



  • Zeig mal lieber die Stelle, wo der Mutex benutzt wird.



  • Forum WinAPI wäre korrekt.



  • hallo leute, ich hab nochmal bischzen alles durchdebuggt, und bin auf

    folgenes gestoßen:

    Thread A durchläuft zyklisch folgenden Code und führt eine Message im Fenster X aus:

    m_Mutes.Acquire ();
    ::SendMessage(m_hWnd,WM_PR2_DATASTATE,(WPARAM)it->c_str(),NULL); //Hier hängt er sich auf
    m_Mutex.Release();
    

    Zur gleichen Zeit drück ich ein Button im Fenster X, welcher ein
    Messageevent OnClick aufruft in dem ich dieses tu:

    void CThreadTest::OnBnClickedTransfer()
    {
    m_Mutes.Acquire ();
    ...
    m_Mutex.Release();
    

    }
    d.h. Während er noch die Message der Thread A bearbeitet (welche in Fenster X implementiert ist), drück ich einen Button (welcher in Fenster X sitzt) welcher auch eine Message auslöst.. bumm...



  • Du hast einen Deadlock erkannt, nun behebe ihn.



  • BorisDieKlinge schrieb:

    hallo leute, ich hab nochmal bischzen alles durchdebuggt, und bin auf

    folgenes gestoßen:

    Thread A durchläuft zyklisch folgenden Code und führt eine Message im Fenster X aus:

    m_Mutes.Acquire ();
    ::SendMessage(m_hWnd,WM_PR2_DATASTATE,(WPARAM)it->c_str(),NULL); //Hier hängt er sich auf
    m_Mutex.Release();
    

    Zur gleichen Zeit drück ich ein Button im Fenster X, welcher ein
    Messageevent OnClick aufruft in dem ich dieses tu:

    void CThreadTest::OnBnClickedTransfer()
    {
    m_Mutes.Acquire ();
    ...
    m_Mutex.Release();
    

    }
    d.h. Während er noch die Message der Thread A bearbeitet (welche in Fenster X implementiert ist), drück ich einen Button (welcher in Fenster X sitzt) welcher auch eine Message auslöst.. bumm...

    Messages von einem anderen Thread and den UI Thread musst du mit PostMessage verschicken. SendMessage ist blockierend und damit hast du wie "Sehr schön" richtig erkannt hat einen Deadlock.

    Edit: Wobei das auch nicht immer hilft. Ich verschiebe den Thread mal nach WinAPI 😉
    Edit2: eventuell hilft auch SendMessageAsync ^^
    BR
    Vinzenz



  • Dieser Thread wurde von Moderator/in evilissimo aus dem Forum C++ in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • @evilissimo: danke, so ein deadlock zu erkennen ist gar net so einfach;) ich schau mir mal SendMessageAsync an;)

    thx jungs



  • BorisDieKlinge schrieb:

    Hab ne dafür ne Mutex klasse geschrieben:

    wieso schreibt jemand eine klasse für 3 einfach zu verwendende funktionen?
    🙂



  • fricky schrieb:

    BorisDieKlinge schrieb:

    Hab ne dafür ne Mutex klasse geschrieben:

    wieso schreibt jemand eine klasse für 3 einfach zu verwendende funktionen?
    🙂

    weil die leute dank des c++ marketing wahns (und durch die teils diletantischen buchempfehlungen von mitgliedern hiesigen forums) den eindruck gewonnen haben, sie müssten alles, aber auch alles, in klassen stopfen, weil ihr code dann modularer und besser sei, etc. typisch c++'ler halt, machens sich immer komplizierter als nötig :lol:



  • fricky schrieb:

    BorisDieKlinge schrieb:

    Hab ne dafür ne Mutex klasse geschrieben:

    wieso schreibt jemand eine klasse für 3 einfach zu verwendende funktionen?
    🙂

    weil der destruktor der klasse unheimlich hilfreich ist



  • raii schrieb:

    weil der destruktor der klasse unheimlich hilfreich ist

    aber das critical-section object ist danach auch ungültig, wenn es ein object-member ist. legt man es statisch an, benutzen alle objecte die selbe CS. das bringt auch nix. also besser keine klasse drum herumstricken.
    🙂



  • 😕 😕 😕 😕 😕



  • class Mutex
    {
        CRITICAL_SECTION *cs;
    
    public:
        Mutex (CRITICAL_SECTION *sect) 
        {
           cs = sect; 
           EnterCriticalSection (cs);
        }
    
        ~Mutex() 
        {
          LeaveCriticalSection (cs);
        }
    };
    ...
    CRITICAL_SECTION the_section;
    ...
    void f()
    {
       Mutex m (&the_section);
       // Locked
       ...
    } // Unlocked
    ...
    

    sinnvoller wäre sowas^^
    🙂



  • Und dein Code funktioniert nicht mal.. Genau deshalb verwendet man Klassen, damit man nicht den Aufruf zu InitializeCriticalSection vergisst. Abgesehen davon ist es doch auch üblich, eine Mutex- und eine MutexLocker- (o.s.ä.) Klasse zu haben.

    edit: übrigens auch und vor allem wegen Exceptions, die überspringen beim "Wurf" ja einfach das "Release".



  • Badestrand schrieb:

    Und dein Code funktioniert nicht mal.. Genau deshalb verwendet man Klassen, damit man nicht den Aufruf zu InitializeCriticalSection vergisst.

    stimmt. ich blindfisch 😞

    Badestrand schrieb:

    Abgesehen davon ist es doch auch üblich, eine Mutex- und eine MutexLocker- (o.s.ä.) Klasse zu haben.

    nö, mein misslungenes beispiel beweisst doch eindeutig, daß man sowas nicht in klassen packen sollte. wo willst du da das InitializeCriticalSection unterbringen?
    🙂



  • Badestrand schrieb:

    edit: übrigens auch und vor allem wegen Exceptions, die überspringen beim "Wurf" ja einfach das "Release".

    unter windows hast du dafür '__finally'
    übrigens ist SEH weitaus nützlich als C++ exceptions
    🙂



  • fricky schrieb:

    Badestrand schrieb:

    Und dein Code funktioniert nicht mal.. Genau deshalb verwendet man Klassen, damit man nicht den Aufruf zu InitializeCriticalSection vergisst.

    stimmt. ich blindfisch 😞

    hihi :p

    fricky schrieb:

    nö, mein misslungenes beispiel beweisst doch eindeutig, daß man sowas nicht in klassen packen sollte. wo willst du da das InitializeCriticalSection unterbringen?
    🙂

    class Mutex{
    
        CRITICAL_SECTION _critSection;
    
    public:
    
        Mutex () { InitializeCriticalSection (& _critSection); }
        ~Mutex () { DeleteCriticalSection (& _critSection); }
    
        void Acquire(){ EnterCriticalSection (& _critSection); }
        void Release(){ LeaveCriticalSection (& _critSection); }
    };
    
    class MutexLocker
    {
        Mutex& cs;
    
    public:
        MutexLocker( Mutex& m ) : cs(m)
        {
           cs.Acquire();
        }
    
        ~MutexLocker()
        {
            cs.Release();
        }
    };
    
    ...
    Mutex the_section;
    ...
    
    void f()
    {
       MutexLocker m (the_section);
       // Locked
       ...
    } // Unlocked
    

    Meinetwegen auch mit "friend", damit man auf Aquire und Release keinen Zugriff mehr hat 🙂



  • fricky halt einfach deine fresse wenn du keine ahnung hast



  • sowas hab ich auch noch^^ immer cool bleiben

    class Lock {
    
    private:
    
        Mutex & _mutex;
    
    public:
        // Acquire the state of the semaphore
        Lock (Mutex &mutex): _mutex(mutex){
            _mutex.Acquire();
        }
    
    	// Release the state of the semaphore
        ~Lock (){ _mutex.Release();	}
    
    };
    


  • BorisDieKlinge schrieb:

    sowas hab ich auch noch^^ immer cool bleiben

    Gut, man kann ja nie wissen 😉

    fricky schrieb:

    Badestrand schrieb:

    edit: übrigens auch und vor allem wegen Exceptions, die überspringen beim "Wurf" ja einfach das "Release".

    unter windows hast du dafür '__finally'

    Joar, aber dann musst du ja schon wieder an was denken, ich mag's automatisch (beim Programmieren) 🙂

    fricky schrieb:

    übrigens ist SEH weitaus nützlich als C++ exceptions
    🙂

    Das verstehe ich nicht, sind die C++-Exceptions nicht genau "Structured Exception Handling"?


Anmelden zum Antworten