无锁的安全栈

#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();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值