为什么 std::atomic::compare_exchange_xxx() 的预期参数不是 const &?
Why is the expected parameter to std::atomic::compare_exchange_xxx() not const &?
我确定我马上就要打脸了,但这里是:
std::atomic::compare_expected_*
的原型是
bool compare_exchange_strong (T& expected, T val,
memory_order sync = memory_order_seq_cst) volatile noexcept;
为什么 expected
不是 const T &
?
static const handle_t INVALID_HANDLE = 0;
...
std::atomic<handle_t> handle(INVALID_HANDLE);
...
handle.compare_exchange_strong(INVALID_HANDLE, newValue);
难道交换方法不需要修改期望值吗?
失败时修改 expected
。
Atomically compares the object representation of *this
with that of expected
, and if those are bitwise-equal, replaces the former with desired (performs read-modify-write operation). Otherwise, loads the actual value stored in *this
into expected
(performs load operation).
TL;DR: 因为如果预期参数是 const
引用,那么当交换失败时 compare_exchange
将无法修改它。
您向 compare_exchange
提供了 预期 和 期望 值。
如果它发现与您提供的值不同的值,它会修改您的期望值。在这种情况下,期望值不会被您提供的所需值替换(即,它无法交换,因此您可能想再次尝试交换该值)。
通常,您想在循环中使用这些函数,因此修改您提供的预期值是有意义的,因为它为您提供了预期的 更新 版本价值。
考虑以下原子:
std::atomic<int> a = 7;
并且您想将 a
的值加倍:
int expected = a.load(), desired;
do {
desired = 2 * expected;
} while (!a.compare_exchange_weak(expected, desired));
在上面的代码中,如果 a
在交换发生之前被另一个线程更改,则 expected
由 compare_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));
我确定我马上就要打脸了,但这里是:
std::atomic::compare_expected_*
的原型是
bool compare_exchange_strong (T& expected, T val,
memory_order sync = memory_order_seq_cst) volatile noexcept;
为什么 expected
不是 const T &
?
static const handle_t INVALID_HANDLE = 0;
...
std::atomic<handle_t> handle(INVALID_HANDLE);
...
handle.compare_exchange_strong(INVALID_HANDLE, newValue);
难道交换方法不需要修改期望值吗?
失败时修改 expected
。
Atomically compares the object representation of
*this
with that ofexpected
, and if those are bitwise-equal, replaces the former with desired (performs read-modify-write operation). Otherwise, loads the actual value stored in*this
intoexpected
(performs load operation).
TL;DR: 因为如果预期参数是 const
引用,那么当交换失败时 compare_exchange
将无法修改它。
您向 compare_exchange
提供了 预期 和 期望 值。
如果它发现与您提供的值不同的值,它会修改您的期望值。在这种情况下,期望值不会被您提供的所需值替换(即,它无法交换,因此您可能想再次尝试交换该值)。
通常,您想在循环中使用这些函数,因此修改您提供的预期值是有意义的,因为它为您提供了预期的 更新 版本价值。
考虑以下原子:
std::atomic<int> a = 7;
并且您想将 a
的值加倍:
int expected = a.load(), desired;
do {
desired = 2 * expected;
} while (!a.compare_exchange_weak(expected, desired));
在上面的代码中,如果 a
在交换发生之前被另一个线程更改,则 expected
由 compare_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));