![](/img/trans.png)
[英]shared_ptr's std::atomic_compare_exchange_strong comparing with raw pointer
[英]When should std::atomic_compare_exchange_strong be used?
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));
有人可以给出比较和交换不在循环中的示例,以便强版本更可取吗?
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
相同的效果的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])更高效的代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.