为什么 std::atomic:<T>:compare_exchange_* 不应该受到 ABA 问题的困扰?
Why does std::atomic<T>::compare_exchange_* should not suffer from ABA issue?
在一些论坛和书籍中(即C++操作中的并发)有一个很好的多生产者/多消费者堆栈的例子,在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<T>: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中列出7.9),我们会发现问题不会发生。当使用共享指针时,old_head不会被删除,因为我们的线程仍然保留对它的引用,因为这样一个新创建的头无法在旧头的内存地址中创建。
在官方的Concurrent in Action Manning论坛上也有一个关于堆栈实现中ABA问题的帖子。
相关文章:
- 警告处理为错误这里有什么问题
- 最小硬币更换问题(自上而下方法)
- 为"adjacent"变量赋值时出现问题
- 我的神经网络不起作用 [XOR 问题]
- 在Ubuntu 16.04上安装Cilk时出现问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 编译包含字符串的代码时遇到问题
- Project Euler问题4的错误解决方案
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 静态数据成员的问题-修复链接错误会导致编译器错误
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 一个关于在C++中重载布尔运算符的问题
- 首要问题的答案让值班员搞错了
- setlocale的C++土耳其字符串问题
- 这个危险指针示例是否因为 ABA 问题而存在缺陷?
- 为什么 std::atomic:<T>:compare_exchange_* 不应该受到 ABA 问题的困扰?
- boost如何在32位机器上避免ABA问题
- 如何在这个无锁堆栈函数中防止未定义的行为和ABA问题