为什么std :: atomic :: compare_exchange_xxx()的预期参数不是const&?

Mar*_*tin 2 c++ atomic std c++11

我相信我即将有一个面子,但这里有:

原型std::atomic::compare_expected_*

bool compare_exchange_strong (T& expected, T val,
       memory_order sync = memory_order_seq_cst) volatile noexcept;
Run Code Online (Sandbox Code Playgroud)

为什么expected不是const T &

static const handle_t INVALID_HANDLE = 0;
...
std::atomic<handle_t> handle(INVALID_HANDLE);
...
handle.compare_exchange_strong(INVALID_HANDLE, newValue);
Run Code Online (Sandbox Code Playgroud)

当然交换方法不需要修改预期值吗?

眠りネ*_*ネロク 6

TL; DR:因为如果预期参数是const引用,那么compare_exchange当交换失败时将无法修改它.


您同时提供预期期望的价值compare_exchange.如果它找到的值与您提供的值不同,它会修改您的预期值.在这种情况下,期望值不会被您提供的期望值替换(即,它无法交换,因此您可能希望尝试再次交换该值).

通常,您希望在循环中使用这些函数,因此修改您提供的预期值是有意义的,因为它为您提供了期望值的更新版本.

考虑以下原子:

std::atomic<int> a = 7;
Run Code Online (Sandbox Code Playgroud)

你想要加倍的价值a:

int expected = a.load(), desired;
do {
  desired = 2 * expected;
} while (!a.compare_exchange_weak(expected, desired));
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,如果a在交换发生之前由另一个线程更改,expectedcompare_exchange使用在a尝试执行交换时(即,在失败时)的值更新.

否则,如果在失败的情况下expected没有修改,则compare_exchange必须a在循环的每次迭代中加载值以进行更新expected:

int expected, desired;
do {
  expected = a.load(); // <-- load on each iteration
  desired = 2 * expected;
} while (!a.compare_exchange_weak(expected, desired));
Run Code Online (Sandbox Code Playgroud)