首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >什么时候应该使用std::atomic_compare_exchange_strong?

什么时候应该使用std::atomic_compare_exchange_strong?
EN

Stack Overflow用户
提问于 2013-07-29 01:05:05
回答 1查看 8.2K关注 0票数 9

C++11中有两个原子CAS操作:atomic_compare_exchange_weakatomic_compare_exchange_strong

根据cppreference

函数的弱形式允许伪造失败,也就是说,即使它们是相等的,也可以表现为*obj != *预期的。当比较和交换处于循环状态时,弱版本将在某些平台上获得更好的性能。当弱比较和交换需要一个循环,而强比较和交换不需要循环时,强比较和交换就更适合了。

以下是使用弱版本的示例,我认为:

代码语言:javascript
运行
复制
do {
    expected = current.value();
    desired = f(expected);
} while (!current.atomic_compare_exchange_weak(expected, desired));

有人能给出一个例子,说明比较和交换不是在循环中,所以强版本更好吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-07-29 01:47:41

atomic_compare_exchange_XXX函数用观察到的值更新它们的“预期”参数,因此您的循环与以下相同:

代码语言:javascript
运行
复制
expected = current;
do {
    desired = f(expected);
} while (!current.atomic_compare_exchange_weak(expected, desired));

如果所需的值独立于期望值,则此循环将变成:

代码语言:javascript
运行
复制
desired = ...;
expected = current;
while (current.atomic_compare_exchange_weak(expected, desired))
  ;

让我们添加一些语义。假设有几个线程同时运行。在每种情况下,desired都是当前线程的非零ID,current用于提供互斥,以确保某些线程执行清理任务。我们并不关心哪个线程,但是我们希望确保某些线程能够访问(也许其他线程可以通过从current读取它的ID来观察胜利者)。

我们可以通过以下方式实现所需的语义:

代码语言:javascript
运行
复制
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相同的效果,因为虚假的故障是可能的:

代码语言:javascript
运行
复制
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)。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17914630

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档