C++11中有两个原子CAS操作:atomic_compare_exchange_weak
和atomic_compare_exchange_strong
。
根据cppreference
函数的弱形式允许伪造失败,也就是说,即使它们是相等的,也可以表现为*obj != *预期的。当比较和交换处于循环状态时,弱版本将在某些平台上获得更好的性能。当弱比较和交换需要一个循环,而强比较和交换不需要循环时,强比较和交换就更适合了。
以下是使用弱版本的示例,我认为:
do {
expected = current.value();
desired = f(expected);
} while (!current.atomic_compare_exchange_weak(expected, desired));
有人能给出一个例子,说明比较和交换不是在循环中,所以强版本更好吗?
发布于 2013-07-29 01:47:41
atomic_compare_exchange_XXX
函数用观察到的值更新它们的“预期”参数,因此您的循环与以下相同:
expected = current;
do {
desired = f(expected);
} while (!current.atomic_compare_exchange_weak(expected, desired));
如果所需的值独立于期望值,则此循环将变成:
desired = ...;
expected = current;
while (current.atomic_compare_exchange_weak(expected, desired))
;
让我们添加一些语义。假设有几个线程同时运行。在每种情况下,desired
都是当前线程的非零ID,current
用于提供互斥,以确保某些线程执行清理任务。我们并不关心哪个线程,但是我们希望确保某些线程能够访问(也许其他线程可以通过从current
读取它的ID来观察胜利者)。
我们可以通过以下方式实现所需的语义:
expected = 0;
if (current.atomic_compare_exchange_strong(expected, this_thread)) {
// I'm the winner
do_some_cleanup_thing();
current = 0;
} else {
std::cout << expected << " is the winner\n";
}
在这种情况下,atomic_compare_exchange_weak
需要一个循环才能实现与atomic_compare_exchange_strong
相同的效果,因为虚假的故障是可能的:
expected = 0;
while(!current.atomic_compare_exchange_weak(expected, this_thread)
&& expected == 0))
;
if (expected == this_thread) {
do_some_cleanup_thing();
current = 0;
} else {
std::cout << expected << " is the winner\n";
}
该标准表明,在这种情况下,实现可以为atomic_compare_exchange_strong
提供比使用..._weak
循环更高效的代码(§29.6.5/25 atomics.types.operations.req)。
https://stackoverflow.com/questions/17914630
复制相似问题