C语言中的原子交换

C语言中的原子交换,c,macos,atomic,c11,C,Macos,Atomic,C11,我想我错过了一些明显的东西。我有这样的代码: int *a = <some_address>; int *b = <another_address>; [...] int *tmp = a; a = b; b = tmp; int*a=; int*b=; [...] int*tmp=a; a=b;b=tmp; 我想原子化地做这件事。我一直在研究\uuuC11\uAtomic\uExchange和OSX上的OSAtomic方法,但似乎没有任何东西能够在原子上执行直接交换

我想我错过了一些明显的东西。我有这样的代码:

int *a = <some_address>;
int *b = <another_address>;
[...]
int *tmp = a;
a = b; b = tmp;
int*a=;
int*b=;
[...]
int*tmp=a;
a=b;b=tmp;
我想原子化地做这件事。我一直在研究
\uuuC11\uAtomic\uExchange
和OSX上的OSAtomic方法,但似乎没有任何东西能够在原子上执行直接交换。它们都可以将一个值原子地写入两个变量中的一个,但决不能同时写入两个变量


有什么想法吗?

这取决于您的体系结构,以及什么是有效和高效的。在任何情况下,您都需要要交换的两个指针在内存中是相邻的,最简单的方法是将它们作为类似对象

typedef struct pair { void *a[2]; } pair;
然后,如果您有一个完整的C11编译器,您可以使用
\u Atomic(pair)
作为原子类型来交换这样一个
对的内容:首先在临时中加载实际的对,用交换的两个值构造一个新的对,进行比较交换以存储新值,并在必要时进行迭代:

inline
void pair_swap(_Atomic(pair) *myPair) {
  pair actual = { 0 };
  pair future = { 0 };

  while (!atomic_compare_exchange_weak(myPair, &actual, future)) {
      future.a[0] = actual.a[1];
      future.a[1] = actual.a[0];
  }
}
根据您的体系结构,这可能是通过无锁原语操作实现的,也可能不是。现代64位体系结构通常有128位原子,这可能只产生一些128位汇编指令


但这在很大程度上取决于在您的平台上实现原子学的质量。将为您提供一个实现原子操作的“函数式”部分的实现,并在检测到时支持128位交换;在我的机器(64位Intel linux)上,这可以有效地编译成
lock cmpxchg16b
指令。

缺少的是,没有操作可以同时与两个内存位置进行原子交互。如果你想以原子方式交换两个对象,你需要用某种互斥来保护它们。谢谢Casey,这真是个蠢货!片刻。。。