#include <iostream>
#include<atomic>
#include<thread>
template<typename T>
class lock_free_stack {
private:
std::atomic<unsigned>threads_in_pop;
struct node {
std::shared_ptr<T>data;
node* next;
node(T const& data_) :data(std::make_shared<T>(data_)) {}
};
std::atomic<node*>head;
std::atomic<node*>to_be_deleted;
static void delete_nodes(node*nodes){
while (nodes) {
node* next = nodes->next;
delete nodes;
nodes = next;
}
}
void chain_pending_nodes(node* nodes) {
node* last = nodes;
while (node* const next = last->next) {
last = next;
}
chain_pending_nodes(nodes, last);
}
void chain_pending_nodes(node* first, node* last) {
last->next = to_be_deleted;
while (!to_be_deleted.compare_exchange_weak(last->next, first));
}
void chain_pending_node(node* n) {
chain_pending_nodes(n, n);
}
void try_reclaim(node* old_head) {
if (threads_in_pop == 1) {
node* nodes_to_delete = to_be_deleted.exchange(nullptr);
if (!--threads_in_pop) {
delete nodes_to_delete;
}
else if (nodes_to_delete) {
chain_pending_nodes(nodes_to_delete);
delete old_head;
}
}
else {
chain_pending_node(old_head);
--threads_in_pop;
}
}
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() {
++threads_in_pop;
node* old_head = head.load();
while (old_head && !head.compare_exchange_strong(old_head, old_head->next));
std::shared_ptr<T>res;
if (old_head) {
res.swap(old_head->data);
}
try_reclaim(old_head);
return res;
}
};
lock_free_stack<int>stk;
const int MAXN = 100;
void push_stack(){
for (int i = 1; i <= MAXN; ++i) {
int t = rand();
std::cout << "插入数据:" << t<< "\n";
stk.push(t);
}
}
std::atomic<int> tot = 1;
void pop_stack() {
while (tot <= MAXN) {
auto x = stk.pop();
if (x != nullptr) {
std::cout << "第" << tot << "次弹栈\n";
std::cout << "弹出数据:" << *x << "\n";
++tot;
}
else std::cout << "栈为空!\n";
}
}
int main(){
std::thread t1(push_stack);
std::thread t2(push_stack);
std::thread t3(pop_stack);
std::thread t4(pop_stack);
t1.join();
t2.join();
t3.join();
t4.join();
}
无锁的安全栈
最新推荐文章于 2024-11-05 17:16:24 发布