首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++11无锁堆栈

C++11无锁堆栈
EN

Stack Overflow用户
提问于 2014-06-30 15:36:11
回答 2查看 874关注 0票数 6

我正在阅读安东尼·威廉姆斯的“在行动中的C++并发”,并且不理解它的lock_free_stack类的push实现。

为什么原子load不在Why循环中?他说的原因是:

因此,您不必每次通过循环重新加载head,因为编译器为您做了这些工作。

但我不明白。有人能解释一下这件事吗?

代码语言:javascript
复制
template<typename T>
class lock_free_stack
{
private:
 struct node
 {
   T data;
   node* next;
   node(T const& data_) : 
     data(data_)
   {}
 };
 std::atomic<node*> head;
public:
 void push(T const& data)
 {
   node* const new_node=new node(data); 
   new_node->next=head.load(); 
   while(!head.compare_exchange_weak(new_node->next,new_node)); 
 }
};
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-06-30 16:03:48

键位于compare_exchange_weak的接口中,在本例中,该接口包含2个参数。第一个是对期望值的引用,第二个是对期望值的引用。如果原子的当前值不等于预期的输入,它将返回false,并将预期的输入设置为当前值。

所以在这种情况下,它所做的就是设置new_node->next = head。然后,如果head仍然等于new_node->next,则将其转换为head。如果它不再是该值,它将使用对new_node->next的引用来为它分配head的当前值。因为失败的循环的每一次迭代都用当前的new_node->nexthead替换了head,所以在循环的正文中没有重复的读取。

票数 6
EN

Stack Overflow用户

发布于 2014-06-30 16:04:33

来自compare_exchange_weak的文档

原子地将存储在*中的值与预期值进行比较,如果它们相等,则用所需的值替换前者(执行读-修改-写入操作)。否则,将存储在*中的实际值加载到预期中(执行加载操作)。

正如您所看到的,否则head的实际值将加载到预期中。

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

https://stackoverflow.com/questions/24493829

复制
相关文章

相似问题

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