C中的原子交换

Tim*_*Tim 4 c macos atomic c11

我想我在这里遗漏了一些明显的东西.我有这样的代码:

int *a = <some_address>;
int *b = <another_address>;
[...]
int *tmp = a;
a = b; b = tmp;
Run Code Online (Sandbox Code Playgroud)

我想原子地这样做.我一直__c11_atomic_exchange在OSX上查看OSAtomic方法,但似乎没有任何东西可以原子地执行直接交换.他们都可以原子地将值写入2个变量中的1个,但不能同时写入两个变量.

有任何想法吗?

Jen*_*edt 5

这取决于您的架构,有效和高效的可能性.在任何情况下,您都需要将要交换的两个指针在内存中相邻,最简单的就是将它们放在内存中

typedef struct pair { void *a[2]; } pair;
Run Code Online (Sandbox Code Playgroud)

然后,你可以,如果你有一个完整的C11编译器使用_Atomic(pair)作为一个原子型交换这样的内容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];
  }
}
Run Code Online (Sandbox Code Playgroud)

根据您的体系结构,这可能是通过无原始操作实现的.现代64位架构通常具有128位原子,这可能导致只有一些128位汇编指令.

但这在很大程度上取决于平台上原子实现的质量.P99将为您提供实现原子操作的"功能"部分的实现,并且在检测到时支持128位交换; 在我的机器上(64位Intel linux),这有效地编译成一条lock cmpxchg16b指令.