非阻塞线程安全堆栈
Non-blocking thread-safe stack
最近我一直在阅读 Anthony Williams - C++ 并发在行动,我到了作者建议非阻塞线程安全堆栈实现的章节。在 pop() 的第一个实现中,据说该方法不是线程安全的。问题是为什么它不是线程安全的?换句话说 - 有人可以指出我数据竞赛在哪里吗?
#include <memory>
#include <thread>
#include <iostream>
#include <atomic>
using namespace std;
template <class T>
class lock_free_stack
{
private:
struct Node
{
std::shared_ptr<T> data_;
Node *next;
Node(const T& data): data_(std::make_shared<T>(data))
{
}
};
std::atomic<Node *> head;
public:
lock_free_stack() { head.store(nullptr); }
void push(T const& data)
{
Node* const newNode = new Node(data);
newNode->next = head.load();
while(!head.compare_exchange_weak(newNode->next, newNode));
}
// The following function is not thread-safe
std::shared_ptr<T> pop()
{
Node* old_head = head.load();
while (old_head && !head.compare_exchange_weak(old_head, old_head->next)); // Atomically
unique_ptr<Node> deleter;
if(old_head)
deleter.reset(old_head);
return old_head ? old_head->data_ : std::shared_ptr<T>();
}
};
竞争条件是一个线程可以评估old_head->next
,就在调用unique_ptr
的析构函数删除old_head
指向的节点时(或之后)。
相关文章:
- 从不同线程使用int64的不同字节安全吗
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 虚拟决赛作为安全
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 如何将元素添加到数组的线程安全函数?
- C++中的线程安全删除
- 并发安全堆栈接口方法:正确与否?
- Boost 堆栈跟踪异步信号安全吗?
- 线程安全堆栈实现
- 安全分配堆栈分配的阵列
- 繁忙时线程安全堆栈互斥被破坏
- 非阻塞线程安全堆栈
- 静态变量与堆栈变量:线程安全与堆栈大小
- 在堆栈上创建 QLayout 是否安全
- 生产者和使用者函数,用于在操作手册中测试C++并发的线程安全堆栈示例
- 为什么在下面的线程安全堆栈实现中没有死锁
- C++STL堆栈:什么时候pop()是安全的
- 泛型堆栈类的异常安全代码
- 在堆栈展开时使用RAII是否安全?
- 我的简单线程安全堆栈有什么问题?