c++11总结23——CAS(无锁队列)

1. 概念

CAS(Compare And Swap)操作是一条CPU的原子指令,所以不会有线程安全问题。

伪代码实现:

CAS(addr,old,new)

解释:将addr存放的只与old比较,如果等于old,则将new赋值给addr。

c++代码实现:

//输入一个pAddr的地址,在函数内部判断其的值是否与期望值nExpected相等
//如果相等那么就将pAddr的值改为nNew并同时返回true;否则就返回false,什么都不做
 
bool compare_and_swap(int *pAddr, int nExpected, int nNew)
{
    if(*pAddr == nExpected)
    {
        *pAddr = nNew;
        return true;
    }
    else
        return false;
}

2. c++11中的CAS

2.1 API

template< class T >
bool atomic_compare_exchange_weak( std::atomic* obj,
                                   typename std::atomic::value_type* expected,
                                   typename std::atomic::value_type desired ) noexcept;

template< class T >
bool atomic_compare_exchange_weak( volatile std::atomic* obj,
                                   typename std::atomic::value_type* expected,
                                   typename std::atomic::value_type desired ) noexcept;

template< class T >
bool atomic_compare_exchange_strong( std::atomic* obj,
                                     typename std::atomic::value_type* expected,
                                     typename std::atomic::value_type desired ) noexcept;

template< class T >
bool atomic_compare_exchange_strong( volatile std::atomic* obj,
                                     typename std::atomic::value_type* expected,
                                     typename std::atomic::value_type desired ) noexcept;

template< class T >
bool atomic_compare_exchange_weak_explicit( std::atomic* obj,
                                            typename std::atomic::value_type* expected,
                                            typename std::atomic::value_type desired,
                                            std::memory_order succ,
                                            std::memory_order fail ) noexcept;

template< class T >
bool atomic_compare_exchange_weak_explicit( volatile std::atomic* obj,
                                            typename std::atomic::value_type* expected,
                                            typename std::atomic::value_type desired,
                                            std::memory_order succ,
                                            std::memory_order fail ) noexcept;

template< class T >
bool atomic_compare_exchange_strong_explicit( std::atomic* obj,
                                              typename std::atomic::value_type* expected,
                                              typename std::atomic::value_type desired,
                                              std::memory_order succ,
                                              std::memory_order fail ) noexcept;

template< class T >
bool atomic_compare_exchange_strong_explicit( volatile std::atomic* obj,
                                              typename std::atomic::value_type* expected,
                                              typename std::atomic::value_type desired,
                                              std::memory_order succ,
                                              std::memory_order fail ) noexcept;

这些函数是根据std::atomic的成员函数定义的:

1) obj->compare_exchange_weak(*expected, desired)
2) obj->compare_exchange_strong(*expected, desired)
3) obj->compare_exchange_weak(*expected, desired, succ, fail)
4) obj->compare_exchange_strong(*expected, desired, succ, fail)

2.2 参数

obj: 指向要测试和修改的原子对象的指针

expected: 指向预期在原子对象中找到的值的指针

desired: 符合预期的存储在原子对象中的值

succ: 如果比较成功,则读取-修改-写入操作的内存同步顺序。允许所有值

fail: 如果比较失败,则加载操作的内存同步顺序

2.3 返回值

如果*obj等于*expected,返回true。不相等返回false。

个人理解:

//伪代码
if(obj == expected)
{
    obj = desired;
    return true;
}
else 
{
    return false;
}

3. 示例

#include 
 
template
struct node
{
    T data;
    node* next;
    node(const T& data) : data(data), next(nullptr) {}
};
 
template
class stack
{
    std::atomic*> head;
 public:
    void push(const T& data)
    {
        node* new_node = new node(data);
 
        new_node->next = head.load(std::memory_order_relaxed);
 
        //std::memory_order_release: 本线程中,所有之前的写操作完成后才能执行本条原子操作
        //memory_order_relaxed: 不对执行的顺序作任何保证
        while(!std::atomic_compare_exchange_weak_explicit(
                                &head,
                                &new_node->next,
                                new_node,
                                std::memory_order_release,     
                                std::memory_order_relaxed))
                ; 
   }
};
 
int main()
{
    stack s;
    s.push(1);
    s.push(2);
    s.push(3);

    return 0;
}

关于c++11中memory_order的介绍:

https://blog.csdn.net/www_dong/article/details/118659528

你可能感兴趣的:(c++11/17,c++11,无锁队列)