功能满足pop和push,可用移动构造函数,满足线程安全,利用利用单向链表和多线程原子变量原语compare_exchange_weak制成,效率略高于锁式栈,可能会有活锁风险,取决于处理机调度。可copy直接使用,环境为C++11及以上。
#pragma once
#include<atomic>
#include<iostream>
namespace safe_container {
namespace no_mutex {
template<class T>
class stack {
private:
struct node {
std::shared_ptr<T> data;
std::shared_ptr<node> next;
node():data(nullptr),next(nullptr){}
node(T Data) :data(std::make_shared<T>(std::move(Data))), next(nullptr) {}
};
std::atomic<std::shared_ptr<node>> head;
public:
stack() :head(nullptr) {}
void push(T data) {
std::shared_ptr<node> new_node(std::make_shared<node>(std::move(data)));
new_node->next = head.load();
while (!(head.compare_exchange_weak(new_node->next,new_node)));
}
std::shared_ptr<T> pop() {
std::shared_ptr<node> old_head = head.load();
while (old_head && !head.compare_exchange_weak(old_head, old_head->next));
return old_head ? old_head->data : nullptr;
}
};
}
}
以上代码有个缺点是,代码中的std::shared_ptr不一定是无锁实现的,这取决于C++的库是怎么样的,当然可以自己写一个无锁的智能指针,原理并不难,这里就不展示了。如果不需要这么高的无锁并发特性,以上的代码也可以凑合着用了,比基本的有锁并发栈还是有一定程度提升的。