您的位置:首页 > 其它

muduo源码分析:数值原子类封装和gcc提供的原子性操作

2015-12-03 16:15 323 查看
// 原子相加操作,先获取值*ptr加上value,返回原来的值

type __sync_fetch_and_add (type *ptr, type value)

// 原子比较和交换(设置)操作

type __sync_val_compare_and_swap (type *ptr, type oldval ,type newval) //先判断*ptr是否等于oldval,如果相等则把*ptr设置成newval,返回操作之前的数

bool __sync_bool_compare_and_swap (type *ptr, type oldval ,type newval) // 先比较在设置,如果比较不等就不会设置

// 原子赋值操作

type __sync_lock_test_and_set (type *ptr, type value)

使用这些原子性操作,编译的时候需要加-march=cpu-type 一般 -march=native本地cpu类型,自动检测

无锁队列实现

http://coolshell.cn/articles/8239.html

注意volatile value_ 告诉编译不要优化,不要读值的时候不要从寄存器中读,每次要从内存中读值,避免数据修改了,读了寄存器中的脏数据

#ifndef MUDUO_BASE_ATOMIC_H
#define MUDUO_BASE_ATOMIC_H

#include <boost/noncopyable.hpp>
#include <stdint.h>

namespace muduo
{

namespace detail
{
template<typename T>
class AtomicIntegerT : boost::noncopyable
{
public:
AtomicIntegerT():value_(0)
{
}
T get()
{
return __sync_val_compare_and_swap(&value_,0,0);//比较并设置,返回以前的值
}
T getAndAdd(T x)
{
return __sync_fetch_and_add(&value_,x);
}
T addAndGet(T x)
{
return getAndAdd(x)+x;//因为x是局部变量,其他线程无法引用,所以+x没有问题
}
T incrementAndGet()
{
return addAndGet(1);
}
T decrementAndGet()
{
return addAndGet(-1);
}
void add(T x)
{
getAndAdd(x);
}
void increment()
{
incrementAndGet();
}
void decrement()
{
decrementAndGet();
}
T getAndSet(T newValue)
{
return __sync_lock_test_and_set(&value_,newValue);
}
private:
volatile T value_;
};
}
typedef detail::AtomicIntegerT<int32_t> AtomicInt32;
typedef detail::AtomicIntegerT<int64_t> AtomicInt64;
}
#endif


参考:c++教程网

muduo网络库
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: