CSemaphore



  • Hallo. Ok nochmal. Alle Threads dürfen gleichzeitig auf das Objekt zugreifen. Da brauche ich keinen mechanismus dafür. Brauche eigentlich nur einen Counter der die Zugriffe auf das Objekt zählt und nur wenn der Counter = 0 ist darf das Objekt gelöscht werden.

    Dafür bruche ich meiner Meinung nach eine Semaphore. Nur ich weiß nicht wie anwenden. Kann mir dazu niemand konkrett helfen?



  • Wenn du nur mit zählen willst, ob auf das Objekt zugegriffen wird, reicht doch ein integer...
    Oder geh ich jetzt all zu blauäugig drauf los?



  • ... da wäre ich vorsichtig. ggfs. wird der zugriff durch das Multithreading zerhackt und der Integer ist nicht mehr konsistent.


  • Mod

    JoYpaD schrieb:

    ... da wäre ich vorsichtig. ggfs. wird der zugriff durch das Multithreading zerhackt und der Integer ist nicht mehr konsistent.

    Der Zugriff auf aligned Integer ist IMHO auf allen Rechnern atomar und wird nicht durch einen context switch eines Threads zerhackt.



  • Es können aber Probleme durch re-ordering auftreten.
    Also mindestens InterlockedXX benutzen.
    Simon



  • Achso. Und mit einer Semaphore läst sich das nicht lösen?



  • Oder Du arbeitest einfach mit einem Intelligenten Zeiger (Referenzzählung).

    Wenn mir noch jemand erklären würde wie das funktioniert wäre ich glücklich 🙂



  • In der Funktion B Warte ich mit CSingleLock(&m_semaphaphore). Doch hier wartet nun mein Programm nicht sondern läuft durch. Wieso

    Könnte man mir eine einfache Antwort geben. Auf genau diese Frage!


  • Mod

    Weil es evtl. der selbe Thread ist?



  • Wenn ich die MSDN-Doku eben richtig überflogen habe, dann musst Du in der Lösch-Methode so darauf warten, dass alle anderen Threads draußen sind:

    CSingleLock singleLock(&m_CritSection);
    singleLock.Lock();  // Attempt to lock the shared resource
    if (singleLock.IsLocked())  // Resource has been locked
    {
    //...use the shared resource...
    
    // Now that we are finished, 
    // unlock the resource for others.
    singleLock.Unlock();
    }
    

  • Mod

    Warum verwendest Du keine Smart Pointer?

    Der Main-Thread erzeugt die Daten und übergibt die Smart-Pointer an die Threads.
    Wenn die lette Referenz weg ist, zerstört sich das Objekt von selbst.



  • @ JoYpaD

    Das ist doch das selbe wie

    CSingleLock singleLock(&m_CritSection,TRUE);
    

    mit dem 2ten Parameter wird gleich gelockt. Mit

    singleLock.IsLocked()
    

    warte ich ja nicht das ist ja nur nochmals eine Sicherheitsabfrage. Ob gelockt wurde.



  • Weil es evtl. der selbe Thread ist?
    

    Nein ist es nicht. Das Problem ist ja dass ich meine Semaphore mit 5 initialisiert habe. Sprich 5 Threads dürfen gleichzeitig zugreifen. Was ich ja aber will ist dass 5 Threads das Objekt sperren dürfen. Die Löschfunktion muss aber warten bis alle laufenden Threads beendet sind. Mit CSingleLock dachte ich erreiche das. Jedoch sieht es nun für mich so aus dass ich mit CSingleLock auch in die 5 erlaubten Threads einreihe. Also ob ich nun m_semaphore.Lock mache oder CSingleLock(m_semaphore,TRUE). Kommt eigentlich auf das selbe raus.

    Jetzt ist ja nur die Frage wie schaffe ich es dass die 5 Threads darauf zugreifen dürfen die Löschfunktion aber nur wenn alle beendet sind.

    Martin Richter schrieb:

    Wenn die lette Referenz weg ist, zerstört sich das Objekt von selbst.

    Das solls ja ber nicht. Das Objekt soll nur zerstört werden wenn die Löschfunktion aufgerufen wird. Die wird aber nicht zwingend aufgerufen wenn alle Thrads beendet sind. Sie darf nur nicht ausgeführt werden wenn noch einer am Laufen ist


  • Mod

    Eben. Im Destruktor wird die Löschfunktion aufegrufen.
    Wenn noch eine Referenz existiert (also ein Thread läuft) wird eben nicht gelöscht.

    Ich glaube Du hast da ein totales Code Chaos und hast Semaphoren nicht verstanden.



  • Im Destruktor wird die Löschfunktion aufegrufen.

    Na eben nicht.

    Wenn noch eine Referenz existiert (also ein Thread läuft) wird eben nicht gelöscht.

    Richtig aber wie verhindere ich das. Das ist ja meine Frage

    Ich glaube Du hast da ein totales Code Chaos und hast Semaphoren nicht verstanden.

    Ok dann habe ich halt Semaphore nicht verstanden. Drum frage ich ja hier.


  • Mod

    tanztderbär schrieb:

    Im Destruktor wird die Löschfunktion aufegrufen.

    Na eben nicht.

    Wenn noch eine Referenz existiert (also ein Thread läuft) wird eben nicht gelöscht.

    Richtig aber wie verhindere ich das. Das ist ja meine Frage

    Also nochmal gaaaaaanz langsam zum mitschreiben.

    1. Du baust ein Containerobjekt.
    In dessen Destruktor wird aufgeräumt, so wie Du möchtest
    2. Nun Erzeugst Du dieses Objekt und weist es einem Smart-Pointer zu (es gibt counted pointer, linked pointer), alles wurscht. Hauptsache threadsafe (siehe Boost (http://www.boost.org/doc/libs/1_40_0/libs/smart_ptr/smart_ptr.htm) oder hier http://ootips.org/yonat/4dev/smart-pointers.html.
    3. Nun bekommt jeder Thread eine Kopie des Smartpointers.
    4. Der aufrufende Thread kann nun den Smartpointer vergessen und freigeben.
    5. Nachdem der letzte Thread stirbt räumt der Container auf.

    Das habe ich doch schon so angeraten.
    Das funktioniert ganz unabhängig von der Anzahl der User.

    BTW: Der Smartpointer Code muss evtl. noch mit Interlocked Funktionen threasicher gemacht werden. (Ist bei Boost nicht notwendig).



  • Nachdem der letzte Thread stirbt räumt der Container auf.

    Das soll er aber nicht. So wird das nichts. Egal ich versuch es anders zu machen.



  • tanztderbär schrieb:

    Nachdem der letzte Thread stirbt räumt der Container auf.

    Das soll er aber nicht. So wird das nichts. Egal ich versuch es anders zu machen.

    Naja, du hast ja scheinbar ein komisches Code-Design. So richtig werden wir hier nicht schlau was du genau willst. Andererseits könntestdu das Ding doch beim Beenden des Programmes killen. Spätestens dann müssen die Threads beendet werden, obwohl es meiner Meinung nach Quatsch ist, Ressourcen zu halten, die nicht gebraucht werden.



  • Ressourcen zu halten, die nicht gebraucht werden.

    Die Resourcen werden gebraucht.

    Ich glaube ich werde das nie verstehen von Foren. Ich versuche so genau wie möglich mein Problem einzugrenzen und dies zu beschreiben. Ohne das drum herum. Und will eine Antwort genau auf meine Frage. Dann kommen zig Antworten wie ich es anders machen kann.

    Dann muss ich immer erklären warum dies aus anderen Gründen nicht funktioniert. Und zu guter letzt habe ich dann keine brauchbare Lösung. Schade.


  • Mod

    tanztderbär schrieb:

    Ressourcen zu halten, die nicht gebraucht werden.

    Die Resourcen werden gebraucht.

    Ich glaube ich werde das nie verstehen von Foren. Ich versuche so genau wie möglich mein Problem einzugrenzen und dies zu beschreiben. Ohne das drum herum. Und will eine Antwort genau auf meine Frage. Dann kommen zig Antworten wie ich es anders machen kann.

    Dann muss ich immer erklären warum dies aus anderen Gründen nicht funktioniert. Und zu guter letzt habe ich dann keine brauchbare Lösung. Schade.

    1. Du hast alle antworten bekommen.
    2. Du kannst eine simple Zählvariable mit Interlocked... miteiner CriticalSecion schützen und hochzählen, für jeden Nutzer.und runter zählen für jeden Nutzer der die Daten nicht mehr braucht.
    3. Bei 0 einfach löschen.

    Das ist aber wieder komplizierter als die automatische Freigabe über Smartpointer.

    Ich verabschiede mich aus dem Thread 👎 Ichmuss davon ausgehen, dass Du einfachnicht verstehst und nicht verstehen willst was man Dir sagt.
    Ein schönes sonniges Wochenende!


Anmelden zum Antworten