Mutex für kritische Bereiche



  • Hi,

    ich hätte mal eine Frage bzgl. der Verwendung von Mutex.
    Ich schreibe einen einfachen Proxy, dabei verwende ich einen Mutex um den Zugriff auf ein Array(Ports) zu schützen. Im Hauptthread wird dabei das Sperren und Zulassen der Ports realisiert und in einem Subthread findet die Kommunikation zwischen Client und Server statt. Solange jedoch die Kommunikation läuft, soll nichts am Array verändert werden, sprich das Mutex aktiv sein und wenn kein Client angemeldet ist, möchte ich die möglichkeit haben die Konfiguration zu ändern.
    Mein Problem ist, dass er den Mutex im Hauptthread schon aktiviert und somit ich keinen Client mehr anmelden kann. Wo sollte ich ansetzen um meinen Fehler zu finden?

    Danke im Voraus.

    Edit: Hab den Fehler gerade gefunden, logischer Weise greift sich eine Clientkommunikation das Mutex, sodass ein weiterer Client keine Verbindung aufbauen kann. Das ist natürlich nicht so gewollt, weil sich ja mehrere Clients verbinden sollen???


  • Mod

    Warum verwendest Du einen Mutex und keine Ctrical Section?

    An Deinem Problem ändert sich nichts. Wenn ein neuer Client sich verbinden will benötigt er Zugriff auf den Array...
    IMHO Darfst Du nur den den Zugriff blockieren wenn ein Eintrag in den Array erfolgen soll oder er gelesen werden soll.



  • Ich dachte Mutex und CS unterscheiden sich nicht wesentlich?

    Und an sich hast du recht, du meinst also, dass ich den Mutex nur einsetzen sollte, wenn in meinem Feld nachschaue, ob der port gesperrt ist oder nicht, oder?
    Sprich bei der Kommunikation nichts mache.


  • Mod

    Mutex und CS unterscheiden sich extrem. Ein Mutex ist ein Kernel-Objekt eine CS nicht.
    Ein Mutex ist extrem langsamer als eine CS, besonders wenn es nciht zu einer Kollision kommt.



  • hab jetzt zwar alles schon mit Mutex gemacht, aber vielleicht steige ich ja auch noch um, obwohl es bei so einem kleinen Programm doch nicht so viel aus machen sollte.
    Vielleicht hast du ja mal einen Seite, wo ich ir beide mal im Vergleich anschauen kann. Und zudem wie ich die CS handhabe, ist das genauso einfach wie ein Mutex?


  • Mod

    Es ist viel einfacher.
    Bzw. wenn die die MFC verwendest genauso.

    CCriticalSection critical;
    ...
    
    void TuWasKritisches()
    {
     CSingleLock lock(&critical,TRUE);
     ...
    }
    


  • Danke.
    Wie gebe ich "critical" wieder frei?


  • Mod

    Das macht doch der Destruktor von CSingleLock?

    Wie arbeitest Du denn aktuell mit CMutex?



  • Hier mal ein Bsp.:

    HANDLE hMutex = CreateMutex(NULL,FALSE,"MeinMutex"); 
    
    void TuWasKritisches()
    {
     WaitForSingleObject(hMutex, INFINITE); 
     ...
     ReleaseMutex(hMutex);
    }
    

  • Mod

    Aho! Also pur Windows API.
    Warum postest Du dann hier im MFC Forum? Die MFC hat geniale Wrapperklassen für diese ganzen Sachen. Auch das würde sich mit CSingleLock und CMutex direkt erledigen lassen.



  • Ohh, hatte gar nicht bemerkt, dass ich im falschen Forum bin...



  • Aber CS kann ich doch bei WinAPI auch nutzen, oder?


  • Mod

    Aber sicher!



  • Wie würde es denn dort aussehen, im Vergleich zur MFC?



  • Wenn du ne CRITICAL_SECTION statt einer Mutex verwenden willst, dann musst du bloss ein paar Aufrufe ersetzen:

    WaitForSingleObject(mutexHandle, INFINITE);
    // ->
    EnterCriticalSection(&criticalSection);
    
    ReleaseMutex(mutexHandle);
    // ->
    LeaveCriticalSection(&criticalSection);
    
    BOOL locked = (WaitForSingleObject(mutexHandle, 0) == WAIT_OBJECT_0);
    // ->
    BOOL locked = TryEnterCriticalSection(&criticalSection);
    

    Initialisieren/freigeben:

    CRITICAL_SECTION g_myCriticalSection;
    
    // Initialisieren:
    InitializeCriticalSection(&g_myCriticalSection);
    // oder:
    BOOL success = InitializeCriticalSectionAndSpinCount(&g_myCriticalSection, 1000);
    // 1000 is der Spin-Count, kannste den Wert auch ändern, aber 1000 sollte OK sein
    // - um nen besseren Wert zu finden müsste man mit der endgültigen Anwendung experimentieren (Geschwindigkeit mit verschiedenen Spin-Counts messen)
    
    // Freigeben:
    DeleteCriticalSection(&g_myCriticalSection);
    

Anmelden zum Antworten