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<T>* obj,
typename std::atomic<T>::value_type* expected,
typename std::atomic<T>::value_type desired ) noexcept;
template< class T >
bool atomic_compare_exchange_weak( volatile std::atomic<T>* obj,
typename std::atomic<T>::value_type* expected,
typename std::atomic<T>::value_type desired ) noexcept;
template< class T >
bool atomic_compare_exchange_strong( std::atomic<T>* obj,
typename std::atomic<T>::value_type* expected,
typename std::atomic<T>::value_type desired ) noexcept;
template< class T >
bool atomic_compare_exchange_strong( volatile std::atomic<T>* obj,
typename std::atomic<T>::value_type* expected,
typename std::atomic<T>::value_type desired ) noexcept;
template< class T >
bool atomic_compare_exchange_weak_explicit( std::atomic<T>* obj,
typename std::atomic<T>::value_type* expected,
typename std::atomic<T>::value_type desired,
std::memory_order succ,
std::memory_order fail ) noexcept;
template< class T >
bool atomic_compare_exchange_weak_explicit( volatile std::atomic<T>* obj,
typename std::atomic<T>::value_type* expected,
typename std::atomic<T>::value_type desired,
std::memory_order succ,
std::memory_order fail ) noexcept;
template< class T >
bool atomic_compare_exchange_strong_explicit( std::atomic<T>* obj,
typename std::atomic<T>::value_type* expected,
typename std::atomic<T>::value_type desired,
std::memory_order succ,
std::memory_order fail ) noexcept;
template< class T >
bool atomic_compare_exchange_strong_explicit( volatile std::atomic<T>* obj,
typename std::atomic<T>::value_type* expected,
typename std::atomic<T>::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 <atomic>
template<class T>
struct node
{
T data;
node* next;
node(const T& data) : data(data), next(nullptr) {}
};
template<class T>
class stack
{
std::atomic<node<T>*> head;
public:
void push(const T& data)
{
node<T>* new_node = new node<T>(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<int> 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
|