"==" Operator atomar?
-
uiistdasSchoen schrieb:
hmm, dann sind also alle Operatoren wie !=, >= <,>, <= nicht thread-sicher.
Welche Implementierung von
atomichat denn Vergleichsoperatoren?uiistdasSchoen schrieb:
wie sieht es dann beim "&=" Operator aus der laut C++11 doku atomar ist?
Atomar heißt atomar. Der Operator ist sicher.
-
Ich kann jetzt zwar spontan keine Stelle aus dem Standard zitieren, aber beim Vergleich zwischen T und atomic<T> sollte "operator T() const;" zum Zuge kommen => der Vergleich ist thread safe.
-
wie sieht es mit dem "<<" shift operatoren aus?
-
Ich kann jetzt zwar spontan keine Stelle aus dem Standard zitieren, aber beim Vergleich zwischen T und atomic<T> sollte "operator T() const;" zum Zuge kommen => der Vergleich ist thread safe.
sicher? das steht nun im gegensatz zu ethon_'s Antwort
-
ethon_ schrieb:
mybool == truekannst du dir auf Assemblerebene wie folgt vorstellen:
load mybool testEs ist also sehr wohl möglich, dass der Thread nach dem Laden von mybool unterbrochen wird, ein anderer Thread läuft und mybool auf False setzt -> Race Condition.
Das ist vollkommen wurscht.
Selbst wenn das load + test ein atomarer Block wären könnte die Variable sofort nach diesem Block auffalsegesetzt werden.Fehlen würde nur die "Reaktion" im if bzw. else Zweig mit in den atomaren Block rein zu nehmen. Und das können atomics nicht.
Man kann es aber oft gut mit CAS nachbilden. Und mit transactional memory kann man überhaupt einfach so tun als wäre es so.
-
manni66 schrieb:
Ich kann jetzt zwar spontan keine Stelle aus dem Standard zitieren, aber beim Vergleich zwischen T und atomic<T> sollte "operator T() const;" zum Zuge kommen => der Vergleich ist thread safe.
Oh tatsächlich. Ein impliziter Konvertierungsoperator in einer neuen Komponente der Standardbibliothek. Warum machen die so etwas?
hustbaer schrieb:
Man kann es aber oft gut mit CAS nachbilden. Und mit transactional memory kann man überhaupt einfach so tun als wäre es so.
Was kann man nachbilden? Ein Spinlock?
-
Jetzt bin ich verwirrt.
Sind nun Vergleichsoperatoren (==, !=, <= etc) thread-safe im Sinne des C++-Standards? Wie sieht es mit älteren Standards aus? (Atomar sind sie ja nicht wie ich nun gelernt habe)
-
Wenn du ein atomic Object in einem Vergleich verwendest, wird sein Wert benötigt und das Laden des Wertes erfolgt natürlich atomar. Die Frage ist: Was genau versprichst du dir davon? Anfangen kannst du damit am Ende sowieso nix...
-
Naja, ich würde einfach gerne wissen ob z.B. ein shift auf einem atomic int atomar und thread-safe ist (keine data races). Also z.B.
std::atomic<int> myInt = 9;
myInt = myInt >> 4;
oder
myInt >>= 4;
?
-
Hat keine Data Races, die Operation als Ganzes ist aber nicht atomar...was hat das nun mit == zu tun? Abgesehen davon: Nur weil etwas atomar ist, heißt noch lange nicht, dass Code, der es verwendet, threadsafe ist...
Wenn du wissen willst, was für Operationen atomar sind, wieso nicht einfach in die Doku schauen?
-
Danke aber kannst Du darauf ncohmal genauer eingehen:
Hat keine Data Races
Was hat keine Data races und warum nicht?
-
std::atomic<int> myInt = 9; myInt = myInt >> 4;Hat keine Data Races weil alle nebenläufigen Zugriffe auf geteilte Objekte atomic sind. Es gibt aber keine Garantie darüber, welchen Wert myInt am Ende genau haben wird, wenn dieser Code nebenläufig ausgeführt wird. Das einzige, das gesichert ist, ist, dass es sich um einen der möglichen Werte, die aus einer der möglichen Serialisierungen aller Zugriffe resultieren, handelt...
-
ah, du meinst also es ist nicht thread-safe, aber data race frei sozusagen !?
-
sozusagen...
-
TyRoXx schrieb:
hustbaer schrieb:
Man kann es aber oft gut mit CAS nachbilden. Und mit transactional memory kann man überhaupt einfach so tun als wäre es so.
Was kann man nachbilden? Ein Spinlock?
Atomare "if (cond) do_stuff();" Blöcke.
Mit CAS geht es natürlich nur sehr begrenzt. Und natürlich muss man Retries machen falls einem wer zwischen dem Test und dem CAS für's "updaten" dazwischengefahren ist.
EDIT: Was ich vielleicht dazuschreiben sollte: D.h. ne klassische Spinlock/Mutex muss es oft nicht sein. So Sachen wie "if (a < 123) a++;" lassen sich mit Load + Test + CAS + Retry ganz ohne Spinlock/Mutex machen.
Quasiauto expected = a.load(std::memory_order_relaxed); // Load while (expected < 123) // Test & Retry if (a.compare_exchange_weak(expected, expected + 1)) // CAS break;