gpt4 book ai didi

c++ - 为什么 std::atomic::compare_exchange_* 不应该遭受 ABA 问题?

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:47:26 24 4
gpt4 key购买 nike

在一些论坛和书籍中(即 C++ Concurrency in Action)有一个很好的多生产者/多消费者堆栈的例子,并且在 pop 实现中他们通常这样做以下内容:


// head is an std::atomic<node*> variable
node *old_head = head.load();
while(old_head && !head.compare_exchange_weak(old_head, old_head->next));
...
为什么使用 std::atomic ::compare_exchange_* 可以防止 ABA 问题?
比方说:

  • old_head->next 在线程被抢占之前得到解析(就在compare_exchange_weak之前)
  • 然后 BA 场景发生了
  • 线程恢复后 head == old_head 有效;在这种情况下,old_head->next 不会再次被解析,指向一个无效的内存位置
  • compare_exchange_weak 将被执行,将通过,但值 old_head->next 仍将是 old

然后会发生 ABA 相关问题。

我相信我错过了一些东西。我在这里缺少什么?

干杯

最佳答案

是的,你会在这里遇到 ABA 问题。

不过,我认为这无关紧要,因为您所指的实现(CiA 中的列表 7.3)无论如何都是无效的,它正在泄漏节点。

如果我们看一下最简单的引用计数实现,即使用无锁 std::shared_ptr 的实现(CiA 中的 list 7.9),我们会发现问题不会发生.当使用共享指针时,old_head 不会被删除,因为我们的线程仍然持有对它的引用,因此新创建的 head 无法在旧 head 的内存地址中创建。

官方也有跟帖Concurrency in Action Manning forums关于堆栈实现中的ABA问题。

关于c++ - 为什么 std::atomic<T>::compare_exchange_* 不应该遭受 ABA 问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20173766/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com