Threads: Schreiben auf PODs / atomic sicher ohne Mutex?



  • Hallo,

    habe ich es richtig verstanden, dass der Schreibvorgang auf PODs bzw. atomics ohne Mutex oder sonstige Schutzmaßnahmen trotzdem sicher ist? Es geht nämlich darum, einen bool für jeden Thread zu erstellen, den ich dann zu einem gegebenem Zeitpunkt auf false setzen möchte, um den Thread sicher zu beenden (mit return ).

    Gruß & Danke



  • Nein, da PODs auch structs (wenn von C oder C++ ausgegangen wird) sein koennen, die groesser als ein Register sind. Zweitens: Es haengt von deinem System und Hardware ab. Im neuen C bzw. C++ Standard sind atomics vorgesehen: http://en.cppreference.com/w/cpp/atomic/atomic . Nutze diese!



  • solange es nur einen thread gibt der schreibt und du die datenbereiche fuer die ganze laufzeit der lesenden threads fest allokiert hast (also kein resize wenn schon ein thread liest), ist es sicher.



  • knivil schrieb:

    Nein, da PODs auch structs (wenn von C oder C++ ausgegangen wird) sein koennen, die groesser als ein Register sind.

    Dieser Fall kommt hier nicht vor. Es geht nur um bool .

    knivil schrieb:

    Im neuen C bzw. C++ Standard sind atomics vorgesehen: http://en.cppreference.com/w/cpp/atomic/atomic . Nutze diese!

    Mein Compiler supported diese leider noch nicht (MSVC 2010). Da würde mich doch auch glatt mal interessieren, wie ein atomic technisch funktioniert. Wie kann eine Implementation garantieren, dass es nur einen Schreibvorgang gibt? Oder wie funktioniert das?

    rapso schrieb:

    solange es nur einen thread gibt der schreibt und du die datenbereiche fuer die ganze laufzeit der lesenden threads fest allokiert hast (also kein resize wenn schon ein thread liest), ist es sicher.

    Alles klar, genau das ist der Fall. Vielen Dank!



  • theliquidwave schrieb:

    knivil schrieb:

    Im neuen C bzw. C++ Standard sind atomics vorgesehen: http://en.cppreference.com/w/cpp/atomic/atomic . Nutze diese!

    Mein Compiler supported diese leider noch nicht (MSVC 2010). Da würde mich doch auch glatt mal interessieren, wie ein atomic technisch funktioniert. Wie kann eine Implementation garantieren, dass es nur einen Schreibvorgang gibt? Oder wie funktioniert das?

    CPUs die mehr als einen thread supporten haben spezielle hardware, meistens eine instruktion, die in irgendeiner weise an den speichercontroller gebunden ist und dieser kann garantieren, dass nur eine operation auf eine cacheline ausgefuehrt wird, bzw liefert manchmal zurueck, ob waehrend man die cacheline bearbeitet hat, schon jemand anderes eine modification vornahm. da gibt es mehrere wege, manchmal ueber 'reservation', wie der name schon sagt, reserviert die cpu eine cacheline, du bearbeitest diese, dann uebergibst du diese, falls die reservation verloren ging zwischendurch, scheitert die uebergabe und du faengst von vorne an.
    manchmal ist es etwas komfortabler, dann laedst du dir den wert, den du austauschen willst aus dem speicher, modifizierst ihn und rufst eine atomic swap funktion auf mit dem alten, dem neuen wert und der addresse, und falls der alte wert noch so ist wie angenommen, gibts einen tausch, ansonsten musst du auch hier nochmal von vorn anfangen.
    manchmal ist es so einfach wie eine instruktion, z.b. atomic_add,oder atomic_inc, die garantiert dir dass du den vorherigen wert erhaelst und inkrementiert (bei mancher hardware auch den aktuellen wert nach der inkrementation, ich spreche hier nich von einem standard ;)). manche hardware kann das nur auf bestimten datentypen z.b. 32bit int, manche hat support fuer bytes bis quadwords inklusive floats.

    vergiss nicht, shared variablen volatile zu machen. ansonsten kann ein compiler sowas wie

    while(Buffer[MeineID])
    {
    }
    

    zu sowas umwandeln

    if(Buffer[MeineID])
    while(true)
    {
    }
    


  • Danke für die Erklärung!

    rapso schrieb:

    vergiss nicht, shared variablen volatile zu machen.

    Das hätte ich ja glatt vergessen. Danke für den Hinweis 😉


Anmelden zum Antworten