Auf Intel MacOSX können Sie die integrierten atomaren Operationen des Systems verwenden. Es gibt kein bereitgestelltes atomisches Get oder Set für 32 oder 64 Bit Ganzzahlen, aber Sie können das aus dem bereitgestellten CompareAndSwap erstellen. Möglicherweise möchten Sie die XCode-Dokumentation für die verschiedenen OSAtomic-Funktionen durchsuchen. Ich habe die folgende 64-Bit-Version geschrieben. Die 32-Bit-Version kann mit ähnlich benannten Funktionen ausgeführt werden.
#include <libkern/OSAtomic.h>
// bool OSAtomicCompareAndSwap64Barrier(int64_t oldValue, int64_t newValue, int64_t *theValue);
void AtomicSet(uint64_t *target, uint64_t new_value)
{
while (true)
{
uint64_t old_value = *target;
if (OSAtomicCompareAndSwap64Barrier(old_value, new_value, target)) return;
}
}
uint64_t AtomicGet(uint64_t *target)
{
while (true)
{
int64 value = *target;
if (OSAtomicCompareAndSwap64Barrier(value, value, target)) return value;
}
}
Hinweis, dass Apples OSAtomicCompareAndSwap Funktionen atomar die Operation ausführen:
Wir verwenden diese in dem obigen Beispiel eine Set-Methode zu erstellen, indem man zuerst den alten Wert greifen, dann Speicher das Ziel zu tauschen versucht, die Wert. Wenn der Swap erfolgreich ist, zeigt dies an, dass der Wert des Speichers zum Zeitpunkt des Swap immer noch der alte Wert ist, und während des Swaps (der wiederum atomar ist) erhält er den neuen Wert, also sind wir fertig. Wenn dies nicht gelingt, hat sich ein anderer Thread durch eine Änderung des Werts dazwischen gestört, als wir ihn ergriffen haben und versucht haben, ihn zurückzusetzen. Wenn das passiert, können wir einfach Schleife und versuchen Sie es erneut mit nur minimaler Strafe.
Die Idee hinter der Get-Methode ist, dass wir zuerst den Wert greifen können (was, kann oder kann nicht der tatsächliche Wert, wenn ein anderer Thread stört). Wir können dann versuchen, den Wert mit sich selbst zu vertauschen, einfach um zu überprüfen, ob der anfängliche Zugriff gleich dem atomaren Wert war.
Ich habe dies nicht gegen meinen Compiler überprüft, also bitte alle Tippfehler entschuldigen.
Sie ausdrücklich erwähnt, OSX, aber Sie benötigen, falls auf anderen Plattformen zu arbeiten, hat Windows-eine Reihe von Interlocked * Funktionen, und Sie können sie in der MSDN-Dokumentation suchen. Einige von ihnen funktionieren unter Windows 2000 Pro und höher, und einige (insbesondere einige der 64-Bit-Funktionen) sind neu in Vista. Auf anderen Plattformen verfügen GCC-Versionen 4.1 und höher über verschiedene __sync * -Funktionen, z. B. __sync_fetch_and_add(). Für andere Systeme müssen Sie möglicherweise Assembly verwenden, und Sie finden einige Implementierungen im SVN-Browser für das HaikuOS-Projekt in src/system/libroot/os/arch.
Sie schlagen vor, GCC-Intrinsics zu verwenden, dann sagen Sie dem Compiler nicht zu vertrauen. Beziehen Sie sich auf etwas anderes als intrinsics, die dem Compiler nicht vertraut werden sollten? – Jeff