Threadabsicherung automatisches Enter/Leave CRITICAL_SECTION



  • Ich hab grad einen Tipp bekommen, wenn ich ein automatischen Enter- und LeaveCriticalsection für jede Methode möchte, soll ich doch einfach an den anfang jeder methode ein objekt vom typ eines struct erzeugen in dessen Ctor und Dtor jeweils Enter und Leave aufgerufen werden ...

    Meine frage an euch, kann man das eventuell irgendwie so arrangieren das bei JEDEM methodenaufruf dieser klasse (praktisch ne einrichtung in ner abstrakten klasse von der ich erbe) automatisch ein objekt von dem struct erzeugt wird ??

    damit man sich das mit den critical sections sich praktisch ganz sparen kann ^^



  • Nein



  • mühüüüst ^^ thx trotzdem



  • Ceos schrieb:

    ...wenn ich ein automatischen Enter- und LeaveCriticalsection für jede Methode möchte, soll ich doch einfach an den anfang jeder methode ein objekt vom typ eines struct erzeugen in dessen Ctor und Dtor jeweils Enter und Leave aufgerufen werden ....

    Hi,

    an und für sich ist diese Technik (RAII - Ressource Aquisition Is Initialization) eine tolle Stärke von C++ .... und auch gut für threadsafety zu verwenden.

    Aaaaaaaber: Wenn Du jede Methode damit ausstattest, wird Dir irgendwann das gesamte Multithreading
    a) nichts mehr bringen (bestenfalls), weil sowieso keine 2 Threads mehr parallel ausgeführt werden können und/oder
    b) Du in der weitläufige "Deadlockhölle" versinken (worst case), weil der einzelne Thread über seine eigenen "locks stolpert".

    Vielleicht wusstest Du das schon, aber ich wollte es nicht unerwähnt lassen: Das richtige Locking ist eine seeeehr verzwickte Aufgabe und verlangt eine Menge Gehirnschmalz.

    Gruß,

    Simon2.



  • Ein Thread kann nciht über seine eigenen locks stolpern, CRITICAL_SECTION und die Enter/Leave blockieren nur kontextabhängig also kann ich theoretisch 10 mal EnterCriticalSection(&myCS) in einer Methode aufrufen ohne das er sich festfrisst .... kritisch wird es nur wenn ich irgendwo asynchron werd und nen callback aus nem anderen kontext erwarte der aber wegen nem gelockten Thread nicht ausgeführt wird ...

    das mit der DeadlockHölle hab ich schon hinter mir ^^ da hab ich nu mittlerweilen einiges an routine und n paar OutputDebugString() kniffe hab ich mir schon einfallen lassen um nem deadlock auf die spur zu kommen



  • Ceos schrieb:

    ...
    das mit der DeadlockHölle hab ich schon hinter mir ...

    👍 Glückwunsch !! 😋

    Damit wollte wirklich nicht "den Profi raushängen lassen" (gäb's auch keinen Grund zu), sondern nur helfen, falls benötigt. Wird's nicht: Gut !
    Vielleicht frage ich Dich dann beim nächsten Mal, wenn ich Fragen zum Multithreading habe (allerdings nur für AIX). 😉

    Gruß,

    Simon2.



  • in gewisser weise ist das möglich. zumindest für klassen.
    bzw. deren objekte. Habe aber im moment keinen c++ kompiler parat um das zu testen.

    kannst dazu z.b. noch 2 weitere klassen schreiben, die dann alles automatisieren.

    das "framework" sieht dann so aus:

    template<typename T>
    struct Handler
    {
       explicit Handler(T* t) : t_(t) { EnterCriticalSection(); }
       ~Handler(){ LeaveCriticalSection(); }
    
       // funktioniert das?
       operator (T*) () { return t_; }
    };
    
    template <typename T>
    struct ThreadSaveObject
    {
       explicit ThreadSaveObject(T* t) : t_(t){}
       ~ThreadSaveObject(){ delete t_; }
    
       Handler operator->() return Handler(t_); }
    
       T* t_;
    };
    

    und benutzen wirst du das so

    struct Foo{
       void a(){}
    };
    
    ...
    
    ThreadSaveObejct<Foo> obj(new Foo);
    obj->a();
    

    aber damit schiebst du den verwaltungsaufwand auf den benutzer...



  • Simon2 schrieb:

    b) Du in der weitläufige "Deadlockhölle" versinken (worst case), weil der einzelne Thread über seine eigenen "locks stolpert".

    Nur wenn das locking-primitive nicht "rekursiv" ist. Unter Windows (CRITICAL_SECTION, Mutex) kein Problem.

    Mit PTHREADS ... schon eher 🙂



  • @meister troll
    Deine idee ist gar nicht so übel, das liesse sich sogar vielleicht in ein schon vorhandenes objektdesign einarbeiten, wenn ich die zeit finde werd ich (was heißt hier ich, wir sind eigentlich 3) das mal so testen ^^

    @simon ... fühltest du dich angegriffen ? ich kann deinen post irgendwie nicht interpretieren, falls ja, das war nie in meinem sinne



  • hustbaer schrieb:

    Simon2 schrieb:

    b) Du in der weitläufige "Deadlockhölle" versinken (worst case), weil der einzelne Thread über seine eigenen "locks stolpert".

    Nur wenn das locking-primitive nicht "rekursiv" ist. Unter Windows (CRITICAL_SECTION, Mutex) kein Problem.

    Mit PTHREADS ... schon eher 🙂

    Eben 😉
    ... ich habe halt unter Windows noch nie multithreaded programmiert - und ansonsten nur ein wenig pthreads.

    Gruß,

    Simon2.



  • Ceos schrieb:

    ...@simon ... fühltest du dich angegriffen ? ich kann deinen post irgendwie nicht interpretieren, falls ja, das war nie in meinem sinne

    (Mist: Altes Problem mit "Forenkommunikation" - Ironie und "Nichtironie" sind schwer zu unterscheiden)

    Nein - ich fühle mich nicht angegriffen, sondern wollte im Gegenteil klar machen, dass ich Dich auch nicht "belehren" wollte (damit Du Dich nicht angegriffen fühlst). 😃

    Meine Postings sind alle NICHT ironisch gemeint - ich habe einfach erkannt, dass ich Dir offensichtlich nicht weiterhelfen kann, weil Du auf dem Gebiet mehr Ahnung/Erfahrung hast als ich (was mir aber bei meinem ersten Posting nicht klar war).

    Gruß,

    Simon2.

    P.S.: Auch in diesem post ist KEINE Ironie (Oh Gott - selbst das kann man ironisch (miß)verstehen. 😮



  • GG jaja iss halt so n problem wa ^^

    ich hab nur ne gewisse paranoya entwickelt weil, wenn ich schreibe ich manchmal überheblich wirke und doch immerwieder von irgendwo n trolliger kommentar kommt

    also hier meine generalamnesie für überheblich wirkende posts:

    es tut mir leid, es war nicht so gemeint und wenn es dennoch unverkennbar ist werd ich es auch überarbeiten, oder mich anschliessend förmlich entschuldigen, schliesslich kann jedem mal die "hand ausrutschen" :p

    PS man sollte wirklich als gimick so ne art ironie-Tag in das board einbauen



  • Naja aufn ersten Blick ist die idee den zeigerzugriff zu abstrahieren und da zeugs zwischenzuschieben, pfiffig, aber aufn zweiten Blick in der Praxis greifen wirklich Simons Bedenken.
    Nen Object was jeglichen zugriff lockt, ist designtechnisch schon bedenktlich, und du solltest das multithreading problem noch mal ueberdenken.

    In unserer Praxis fang ich sogar an, in den methodennamen zu kodieren, ob die methode seinen eigenen lock setzt oder nicht.

    Ich mein, wenn du alles lockst, solltest du echt versuchen das MT aufzuloesen und alles in einem thread machen, das ist unkomplizierter und auch performanter.

    wenn du deine threadas schoen entkoppelst und nen "stimmiges" design hasst, hasst du meist auch die schnittpunkte zwischen arbeitsthreads und dem oberflaechenthread ziemlich reduziert und brauchst nur an ganz wenig stellen locken ....
    das schlimmste iss nen design, wenn du objecte schreiben musst, wo jede methode von jedem thread aufgerufen werden kann, dann bist mehr mit locken und unlocken beschaeftigt (unter windows ned so kritisch, aber pthreads & linux sollen da ned so performant sein).

    Ciao ...



  • nunja wirklich JEDEN aufruf zu locken iss .... .... unklug! da haste recht ... da reicht es eigentlich wenn ich einfach nur das threadsave struct in den methoden erzeuge wo ich es auch wirklich brauche ... ich habs mir dennoch kopiert und werd mal schaun was mir dazu noch so einfällt



  • da reicht es eigentlich wenn ich einfach nur das threadsave struct in den methoden erzeuge

    und genau dafuer langt doch der konventionelle weg.

    du legst nen lokale CS an ....
    in methoden wo du nur kurze stuecke sperren musst und keine exceptions geworfen werden, kannst du haendisch locken ....

    willst du ne komplette methode sperren, oder hasst exceptions drinne wo du wieder automatisch entsperren musst nimmst halt die objectlocks, also nen object dem die CS als parameter im constructor uebergibst, das ding sperrt/entsperrt das ding dann im Ctor/dtor

    Mehr braucht man fuer einfachere Sachen eigentlich nicht, codetechnisch gesehen, fuer MT. Der Rest ist eigentlich das design drumherum ...

    Ciao ...



  • Wenn du eh erstmal alle oder den größten Teil der Methoden Lockst, dann brauchst du auch kein Multithreading. Das Problem ist eben, das Shared-State-Multithreading sehr kompliziert ist. Verzichte daher am besten auch Shared-State-Multithreading und schicke die gemeinsam genutzten Daten lieber in Nachrichtenform zwischen den Threads/Prozessen hin und her. (Erlang-style Multithreading)

    Mit MPI kannst du so etwas zB machen



  • naja hierbei geht es um zentrale ressourcen, ich habe mehrere clients die mit identischen daten versorgt werden müssen und da liegt der hase im pfeffer, das ist gar nicht SO einfach ... aber das thema hat sich eigentlich für mich erledigt, es funktioniert erstmal so

    es war mehr als gedankenspiel gedacht, da hier sehr viele helle köpfe im forum sind und es hätte ja sein können das wer DIE IDEE hätte


Anmelden zum Antworten