在Intel MacOSX上,您可以使用内置系统原子操作。 没有为32位或64位整数提供原子获取或设置,但您可以使用提供的CompareAndSwap构建它。 您可能希望在XCode文档中搜索各种OSAtomic功能。 我在下面写了64位版本。 32位版本可以使用类似命名的函数完成。
#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;
}
}
请注意,Apple的OSAtomicCompareAndSwap函数以原子方式执行操作:
if (*theValue != oldValue) return false;
*theValue = newValue;
return true;
我们在上面的例子中使用它来创建一个Set方法,首先获取旧值,然后尝试交换目标内存的值。 如果交换成功,则表示内存的值仍然是交换时的旧值,并且在交换期间给出了新值(它本身是原子的),所以我们完成了。 如果它没有成功,那么其他一些线程通过在我们抓住它和我们试图重置它时修改其间的值来干扰。 如果发生这种情况,我们可以简单地循环并再次尝试,只有最小的惩罚。
Get方法背后的想法是我们可以先获取值(如果另一个线程正在干扰,则可能是也可能不是实际值)。 然后我们可以尝试将值与自身交换,只需检查初始抓取是否等于原子值。
我没有对我的编译器进行检查,所以请原谅任何错别字。
您特别提到了OSX,但是如果您需要在其他平台上工作,Windows有许多Interlocked *功能,您可以在MSDN文档中搜索它们。 其中一些适用于Windows 2000 Pro及更高版本,而一些(特别是一些64位功能)是Vista的新功能。 在其他平台上,GCC 4.1及更高版本具有各种__sync *函数,例如__sync_fetch_and_add()。 对于其他系统,您可能需要使用程序集,您可以在src / system / libroot / os / arch中的HaikuOS项目的SVN浏览器中找到一些实现。