Gibt es Funktionen zum Ausführen von atomaren Operationen (wie Inkrementieren / Dekrementieren einer Ganzzahl) usw., die von der C-Laufzeitbibliothek oder anderen Hilfsprogrammbibliotheken unterstützt werden?
Wenn ja, welche Operationen können mit diesen Funktionen atomar gemacht werden?
Wird es vorteilhafter sein, solche Funktionen als die normalen Synchronisationsgrundelemente wie Mutex usw. zu verwenden?
Betriebssystem: Windows, Linux, Solaris & amp; VxWorks
Die C-Bibliothek hat keine.
Unter Linux bietet gcc etwas - suchen Sie nach __sync_fetch_and_add
, __sync_fetch_and_sub
und so weiter.
Suchen Sie im Fall von Windows nach InterlockedIncrement
, InterlockedDecrement'',
InterlockedExchange 'und so weiter. Wenn Sie gcc unter Windows verwenden, würde ich vermuten, dass es auch die gleichen integrierten Funktionen wie unter Linux hat (obwohl ich das nicht überprüft habe).
Unter Solaris kommt es darauf an. Vermutlich, wenn Sie gcc verwenden, wird es wahrscheinlich (wieder) die gleichen eingebauten Funktionen haben wie unter Linux. Sonst laufen Bibliotheken herum, aber nichts wirklich standardisiertes.
C11 fügte einen (vernünftig) vollständigen Satz von atomaren Operationen und atomaren Typen hinzu. Die Operationen beinhalten Dinge wie atomic_fetch_add
und atomic_fetch_sum
(und *_explicit
Versionen derselben, mit denen Sie das benötigte Bestellmodell angeben können, wobei die Standardversionen immer memory_order_seq_cst
verwenden). Es gibt auch fence
-Funktionen wie atomic_thread_fence
und atomic_signal_fence
.
Die Typen entsprechen den normalen ganzzahligen Typen, z. B. atomic_int8_t
entspricht int8_t
und atomic_uint_least64_t
entspricht uint_least64_t
. Das sind typedef
Namen, die in <stdatomic.h>
definiert sind. Um Konflikte mit bestehenden Namen zu vermeiden, können Sie den Header weglassen; Der Compiler selbst verwendet Namen im Namespace des Implementierers (z. B. _Atomic_uint_least32_t
anstelle von atomic_uint_least32_t
).
"Vorteilhaft" ist situationsbezogen. Die Leistung hängt immer von den Umständen ab. Du kannst erwarten, dass etwas Wunderbares passiert, wenn du einen Mutex für so etwas ausschaltest, aber du bekommst vielleicht keinen Vorteil (wenn es in einem Fall nicht so beliebt ist) oder verschlimmert es (wenn du versehentlich eine 'Spin-Lock' erstellst) .
Auf allen unterstützten Plattformen können Sie GLibs atomare Operationen verwenden. Auf Plattformen, auf denen atomare Operationen eingebaut sind (z. B. Assembleranweisungen), verwendet glib diese. Auf anderen Plattformen wird auf Mutexe zurückgegriffen.
Ich denke, dass atomare Operationen einen Geschwindigkeitsschub geben können, selbst wenn Mutexe mit ihnen implementiert werden. Mit dem Mutex haben Sie mindestens zwei atomare Ops (lock & amp; entriegeln) plus die eigentliche Operation. Wenn die atomare Operation verfügbar ist, handelt es sich um eine einzige Operation.
Nicht sicher, was Sie mit der C-Laufzeitbibliothek meinen. Die richtige Sprache oder die Standardbibliothek bietet Ihnen keine Möglichkeit, dies zu tun. Sie müssten eine betriebssystemspezifische Bibliothek / API verwenden. Lassen Sie sich auch nicht von sig_atomic_t
täuschen - sie sind nicht so, wie es auf den ersten Blick scheint und sind nur im Kontext von Signal-Handlern nützlich.
Unter Windows gibt es InterlockedExchange und ähnliches. Unter Linux können Sie Glibc atomare Makros - sie sind tragbar (siehe i486 atomic.h ). Ich kenne keine Lösung für die anderen Betriebssysteme.
Im Allgemeinen können Sie die Anweisung xchg
auf x86 für atomare Operationen verwenden (funktioniert auch auf Dual-Core-CPUs).
Was Ihre zweite Frage angeht, nein, ich glaube nicht, dass die Verwendung von atomaren Operationen schneller ist als die Verwendung von Mutexen. Zum Beispiel implementiert die Pthreads-Bibliothek bereits Mutexe mit atomaren Operationen, was sehr schnell ist.