java 无锁栈_原子操作的无锁栈

这只是一个push、一个pop的情况,其他待分析。

关于原子操作的几个参数,大概有自己的理解,如果发现有错误,欢迎指出。

code:

template

class lock_free_stack{

private:

struct node;

struct counted_node_ptr {

int external_count;

node* ptr;

};

struct node {

std::shared_ptr data;

std::atomic internal_count;

counted_node_ptr next;

node(T const &data_):

data(std::make_shared(data_)),

internal_count(0)

{}

};

std::atomic head;

void increase_head_count(counted_node_ptr &old_counter) {

counted_node_ptr new_counter;

do {

new_counter = old_counter;

++new_counter.external_count;

}

while(!head.compare_exchange_strong(old_counter, new_counter,

std::memory_order_acquire,

std::memory_order_relaxed)); //需要实时获取head的更新,这是使用memory_order_acquire

old_counter.external_count = new_counter.external_count;

}

public:

~lock_free_stack() {

while(pop());

}

void push(T const &data) {

counted_node_ptr new_node;

new_node.ptr = new node(data);

new_node.external_count = 1;

new_node.ptr->next = head.load(std::memory_order_relaxed);

while(!head.compare_exchange_weak(new_node.ptr->next, new_node,

std::memory_order_release,

std::memory_order_relaxed)); //更新后要及时更新到pop,这是使用memory_order_release

}

std::shared_ptr pop() {

counted_node_ptr old_head = head.load(std::memory_order_relaxed);

for(;;) {

increase_head_count(old_head);

node* const ptr = old_head.ptr;

if (!ptr) {

return std::shared_ptr();

}

if(head.compare_exchange_strong(old_head, ptr->next,

std::memory_order_relaxed)) { //前后没有需要同步的依赖操作,使用memory_order_relaxed

std::shared_ptr res;

res.swap(ptr->data);

int const count_increase = old_head.external_count - 2;

if (ptr->internal_count.fetch_add(count_increase,

std::memory_order_release) == -count_increase) { //修改数据需要及时更新,使用memory_order_release

delete ptr;

}

return res;

}

else if(ptr->internal_count.fetch_add(-1,

std::memory_order_relaxed) == 1) { //无依赖使用memory_order_relaxed

ptr->internal_count.load(std::memory_order_acquire);

delete ptr;

}

}

}

};

摘自《c++并发编程实战》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值