Neuer Weg Thread Synchronisierung in Klassen zu Betreiben?



  • Zu Zeit ist es ja so, will man eine Klasse Threadsicher machen verpasst man ihr eine CRITICAL_SECTION, Mutex oder sonst was für ein Synchronisierungs-Objekt.
    Das hat den Nachteil das die Klasse nicht unwesentlich weckst(oder soll ich sagen Instanzen?), na ja egal wir wissen was ich meine.
    Ein weg um dieses zu umgehen ist für die gesamte Klasse ein statisches sync Objekt anzulegen, was wiederum den Nachteil hat das wenn ein Thread mit einer Instanz grade arbeitet alle andern Threads die mit anderen Instanzen von der Klasse arbeiten wollen auch geblockt werden(untragbar).

    Vor langer Zeit hatte ich mal ne Idee zu und jetzt habe ich sie Implementiert.
    Global wird ein Pool mit sync Objekten angelegt.
    Zu gleich eine Map wo key void* und value ein Pointer auf ein sync Objekt aus den Pool ist.

    Hier an ein Bsp erklärt wozu:

    class foo
    {
    public:
        void memfunc()
        {
             lock( this );
             // hier wird this zu void* konvertiert
             // lock kuckt in der map nach ob dieses void* schon bekannt ist
             // wenn nein wird ein neuer map Eintrag gemacht,
             // aus den pool wird ein sync Objekt entnommen 
             // und den map Eintrag mit der adresse von den this zu gewiesen
             // danach wird das sync Objekt scharf gestellt(oder wie sagt man zu? aktiviert?).
             // Das erzeugen wird übersprungen falls die this Adresse schon in der map ist
    
             ...
    
             unlock( this );
             // unlock such das passende sync Objekt zu der Adresse von this
             // und deaktiviert das sync Objekt
             // falls kein Thread durch das sync Objekt mehr geblock wird,
             // so wird das sync Objekt wieder zurück in den Pool gegeben
             // wo es einer anderen Instanzen gute Dienste leisten kann
        }
    };
    

    Die Vorteile sind:
    Im Schlimmsten Fall werden nur so viele sync Objekt wie Instanzen von den gesyncten Klassen benötig.
    Wie viel % man im Durchschnitt spart ka.
    Objekte werden nicht mehr durch sync Objekte aufgebläht

    Die Nachteile:
    Es muss in der map gesucht werden (kostet Laufzeit, ob sich noch lohnt ka)
    Beim Zugriff auf Pool und Map wird ein extra sync Objekt aktiviert.

    Aber was zähle ich Vor- und Nachteile auf, wenn ich noch nicht mal weis obs was neues ist.

    Hier ist der Quell Code (win32 & mit etwas boost 1.30.0) http://home.arcor.de/gerard.choinka/MutexPoolMain.cpp

    Die Frage: Ist das ein alter Hut?

    [ Dieser Beitrag wurde am 22.03.2003 um 02:19 Uhr von Dimah editiert. ]



  • *push* 😞



  • ich weis nicht genau wie die mutexes eigentlich wirklich funktionieren, ich vermute mal, dass das über das BS läuft. Deine Methode wär eigentlich nicht schlecht, aber wieso die lock-variable static? eine pro instanz genügt doch :). Das problem ist aber, wenn mutex übers bs läuft, dann hakt das ein, bevor du auf die instaz zugreifst. baust du so eine methode in die klasse ein, so kanns sein, dass (grad mit dem modernen hyperthreading [oder hab ich das falsch verstanden]) 2 threads gleichzeitig drauf zugreifen, z.b. währen die lock var auf locked geschaltet wird, wird abgefragt, ob gelockt ist. => ergebnis: unlocked -> zugriff.

    alternativ könntest du einen container bauen, der objekte jeglicher art threadsafe verwahrt, indem du jeden zugriff auf die instanzen über einen globalen container laufen lässt. (werd ich heut abend mal versuchen). aber ob das dann soviel besser ist als das was du meinst, glaub kaum

    [ Dieser Beitrag wurde am 24.03.2003 um 13:01 Uhr von Korbinian editiert. ]



  • Original erstellt von Korbinian:
    2 threads gleichzeitig drauf zugreifen, z.b. währen die lock var auf locked geschaltet wird, wird abgefragt, ob gelockt ist. => ergebnis: unlocked -> zugriff.

    der pool hat extra noch ein sync objekt, das verhindert das zwei threads gleichzeitig auf den pool zurgreifen
    das ist auch einer der nachteile, jedes mal wenn die methode sich locken will wird einmal der pool gelockt (alle andern klassen die locken wollen mussen jetzt warten) dann wird der pool ungelockt und dann das sync objekt für die klasse gelockt
    wenn das locken und unlocken teuer ist dann ist meine methode mist



  • Die Frage: Ist das ein alter Hut?

    Neu ist die Idee jedenfalls nicht. Spontan fällt mir das dazu ein:
    http://msdn.microsoft.com/msdnmag/issues/01/08/Concur/default.aspx



  • Original erstellt von -King-:
    Neu ist die Idee jedenfalls nicht. Spontan fällt mir das dazu ein:
    http://msdn.microsoft.com/msdnmag/issues/01/08/Concur/default.aspx

    bevor ich weiter lese

    // code aus den artikel
    class CritSec
    {
    public:
        CritSec();
        ~CritSec()
            { DeleteCriticalSection(&m_critSec); }
    
        void acquire()
            { EnterCriticalSection(&m_critSec); }
        bool tryAcquire()   // use only on Windows NT or Windows 2000
            { return !!TryEnterCriticalSection(&m_critSec); }
        void release()
            { LeaveCriticalSection(&m_critSec); }
    
    private:
        enum { k_spinCount = 3000ul };
    
        CRITICAL_SECTION m_critSec;
    };
    

    wie kann man solch falschen code public machen?

    • InitializeCriticalSection auf m_critSec wird nicht aufgerufen
    • Kein Copy Ctor und op= definiert, der vom compilier macht so was wie memcpy, CRITICAL_SECTION sind aber nicht copierbar
    • wenn die CRITICAL_SECTION nur ein handle ist für ein von ein objekt vom OS und der copy ctor copiert das handle, wenn jetzt beide objekte auf das gleiche objekt zeigen und ein objekt zerstört wird dann ruft es DeleteCriticalSection auf m_critSec auf aber das andere Obejkt weis von nichts

    [ Dieser Beitrag wurde am 24.03.2003 um 17:45 Uhr von Dimah editiert. ]



  • Original erstellt von -King-:
    Neu ist die Idee jedenfalls nicht. Spontan fällt mir das dazu ein:
    http://msdn.microsoft.com/msdnmag/issues/01/08/Concur/default.aspx

    ähnliche implementierung aber eine anderes ziel,
    auf jeden fall interesant

    [ Dieser Beitrag wurde am 24.03.2003 um 23:46 Uhr von Dimah editiert. ]


Anmelden zum Antworten