并发编程(三): 使用C++11实现无锁stack(lock-free stack)

C++11中CAS实现:

template< class T>
struct atomic
{
public:
    bool compare_exchange_weak( T& expected, T desired,
                                std::memory_order success,
                                std::memory_order failure );
    bool compare_exchange_weak( T& expected, T desired,
                                std::memory_order success,
                                std::memory_order failure ) volatile;
    bool compare_exchange_weak( T& expected, T desired,
                                std::memory_order order =
            std::memory_order_seq_cst );
    bool compare_exchange_weak( T& expected, T desired,
                                std::memory_order order =
            std::memory_order_seq_cst ) volatile;
    bool compare_exchange_strong( T& expected, T desired,
                                  std::memory_order success,
                                  std::memory_order failure );
    bool compare_exchange_strong( T& expected, T desired,
                                  std::memory_order success,
                                  std::memory_order failure ) volatile;    
    bool compare_exchange_strong( T& expected, T desired,
                                  std::memory_order order =
            std::memory_order_seq_cst );
    bool compare_exchange_strong( T& expected, T desired,
                                  std::memory_order order =
            std::memory_order_seq_cst ) volatile;
    ...
};

自动的比较*this的值和expect的值,如果相等,那么将*this的值替换为desired的值(进行读-修改-写操作)。如果不相等,那么将*this的值存到expected处。
success对应于read-modify-write的内存模型;failure则对应于失败时的load。

weak形式允许假失败,该函数直接比较原子对象所封装的值与参数 expected 的物理内容,所以某些情况下,对象的比较操作在使用 operator==() 判断时相等,但 compare_exchange_weak 判断时却可能失败,因为对象底层的物理内容中可能存在位对齐或其他逻辑表示相同但是物理表示不同的值(比如 true 和 2 或 3,它们在逻辑上都表示"真",但在物理上两者的表示并不相同)。可以虚假的返回false(和expected相同)。若本atomic的T值和expected相同则用val值替换本atomic的T值,返回true;若不同则用本atomic的T值替换expected,返回false。  
strong版本的不允许(spuriously 地)返回 false,即原子对象所封装的值与参数 expected 的物理内容相同,比较操作一定会为 true。不过在某些平台下,如果算法本身需要循环操作来做检查, compare_exchange_weak 的性能会更好。因此对于某些不需要采用循环操作的算法而言, 通常采用compare_exchange_strong 更好

#ifndef TG_STACK_LOCK_FREE_H
#define TG_STACK_LOCK_FREE_H

#include <atomic>

template<typename T>
class tg_stack_lock_free
{
public:
    tg_stack_lock_free():_head(nullptr)
    {
    }

    void push(const T& data)
    {
        node* new_node = new node(data);
        new_node->next = _head.load();

        while(!_head.compare_exchange_weak(new_node->next, new_node));
    }

    bool pop(T& data)
    {
        auto result = _head.load();
        while( result != nullptr && !_head.compare_exchange_weak(result,result->next));
        if( !result )
        {
            return false;
        }
        data = result->data;

        delete result;
        return true;
    }

private:
    struct node
    {
        T data;
        node* next;

        node(const T& data) : data(data), next(nullptr) {}
    };
    std::atomic<node*> _head;
};

#endif // TG_STACK_LOCK_FREE_H

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值