2 Stimmen

i++ fadensicher

Es ist der Zusatz zu diese Frage kann ich schlussfolgern, dass eine solche Operation in C/C++ nicht thread-sicher ist.

Meine Frage lautet: Müssen wir erwerben sperren en jeder Fall in Bezug auf die Thread-Sicherheit? Beachten Sie, dass Sperren ein logisches Konzept sind, selbst wenn Sie InterlockedIncrement() oder c++0x atomic type verwenden, wird die Sperre konzeptionell durch die Verwendung von cmpxchg .

Wenn es zum Beispiel nur einen Schreib-Thread und viele Lese-Threads gibt, kann der Lese-Thread dann einen seltsamen Wert erhalten? Ich nehme an

  1. Der Typ i ist 32-Bit auf der x86-Plattform oder 64-Bit auf der x64-Plattform.
  2. Entweder der alte oder der neue Wert ist OK.

4voto

edA-qa mort-ora-y Punkte 27791

Im Falle eines einzelnen Schreibers und vieler Leser dieses einzelnen Wertes ist es thread-safe , aber im allgemeinen Fall sind solche Operationen nicht thread-sicher (daher ist eine Sperre oder die Verwendung von atomaren Operationen erforderlich). Außerdem, was thread-safe Mittel sind hier sehr begrenzt.

Wenn Sie einfach tun i++ in einem Thread, werden die anderen Threads entweder den alten oder den neuen Wert sehen. Auf den beiden von Ihnen genannten Plattformen werden die Werte atomar gespeichert/geladen, so dass sie keinen halben Wert erhalten können. Dies trifft jedoch nicht generell zu, da z. B. ein 64-Bit-Wert auf x86 nicht atomar gespeichert wird, so dass der Leser die Hälfte des alten Wertes und die Hälfte des neuen Wertes erhalten könnte. Also Gewindesicherheit ist hier sehr plattformspezifisch.

Man muss aber trotzdem vorsichtig sein. Wenn es sich um eine einfache int kann der Optimierer den Ladevorgang einfach verwerfen (vielleicht eine Kopie in einem Register behalten). In diesem Fall wird der Leser nie einen neuen Wert erhalten. Dies ist von entscheidender Bedeutung, wenn Sie dies in einer Schleife tun. Leider ist der einzige standardkonforme Weg, dies zu tun, in C++0x die Verwendung einer atomic<T> Typ ( flüchtig erfüllt diesen Zweck jetzt bei einigen Compilern).

Wenn Sie einen zweiten Writer hinzufügen, ist der Inkrement-Operator natürlich überhaupt nicht thread-sicher. Sie könnten hier jedoch eine atomare Hinzufügungsfunktion verwenden, die das Ganze wieder thread-sicher machen würde.

0voto

Alexandre C. Punkte 53706

Wenn Sie Zugang zu Qt haben, schauen Sie sich deren QAtomicInt Klasse. Es ist ziemlich eigenständig, es ist möglich (ich habe es geschafft), alle notwendigen Dinge von dort zu ziehen, um eine eigenständige portable Klasse zu haben. atomic_int Klasse.

Es bietet atomare fetch_and_store , fetch_and_add , compare_and_swap , increment y decrement mit Barriere-Semantik (Acquire, Release, Full, No Barrier), obwohl auf x86 jede Operation eine Full Barrier ist.

Es gibt eine QAtomicPointer Klassenvorlage zu.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X