我正在读“第二行动中的由安东尼威廉姆斯第7.2.2节停止这些讨厌的泄漏:管理内存的无锁数据结构。
在本节之前,我们实现了一个lock_free_stack
template <typename T> class lock_free_stack {
private:
  struct node {
    std::shared_ptr<T> data;
    node *next;
    node(T const &data_) : data(std::make_shared<T>(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));
  }
  std::shared_ptr<T> pop() {
    node *old_head = head.load();
    while (old_head && !head.compare_exchange_weak(old_head, old_head->next));
    return old_head ? old_head->data : std::shared_ptr<T>();
  }
};安东尼在第7.2.2节中说:
当您第一次查看pop()时,您选择了泄漏节点,以避免出现这样的情况:一个线程删除一个节点,而另一个线程仍然保存一个指向它即将取消引用的指针。
--我不明白,如果两个线程同时调用pop(),每个线程将得到不同的头,因此每个线程的old_head彼此不同,它们可以自由地删除old_head。
在我看来,没有内存泄漏的pop()应该是:
  std::shared_ptr<T> pop() {
    node *old_head = head.load();
    while (old_head && !head.compare_exchange_weak(old_head, old_head->next));
    std::shared_ptr<T> res = old_head ? old_head->data : std::shared_ptr<T>();
    delete old_head;
    return res;
  }如何理解安东尼说的话?
发布于 2022-06-30 16:26:49
比赛到了
  while (old_head && !head.compare_exchange_weak(old_head, old_head->next));
                                                           ^^^^^^^^^^^^^^一个可能的竞赛是:
exchange
compare_exchange_weak之前执行自己的操作
https://stackoverflow.com/questions/72818797
复制相似问题