muduo源码学习(3)-原子操作

来源:互联网 发布:highcharts more.js 编辑:程序博客网 时间:2024/05/16 11:35

锁竞争是高性能服务器的杀手之一,所以,对于一些简单的变量的操作,如增加,赋值等,使用原子操作可以避免使用锁,这样更加高效。在c++11中,也提供了原子变量。muduo库中利用gcc原子性操作提供封装了一部分原子操作。在base下的Atomic.h中,源码如下:

template<typename T>class AtomicIntegerT : boost::noncopyable{//boost::noncopyable,不能拷贝的类,将=与拷贝构造函数私有 public:  AtomicIntegerT()    : value_(0)  {  }  // uncomment if you need copying and assignment  //  // AtomicIntegerT(const AtomicIntegerT& that)  //   : value_(that.get())  // {}  //  // AtomicIntegerT& operator=(const AtomicIntegerT& that)  // {  //   getAndSet(that.get());  //   return *this;  // }//获取当前value的值  T get()  {  //类似的__sync_bool_compare_and_swap(&value_, 0, 0);  //先比较,再设置,若比较成功,则返回true    //__sync_val_compare_and_swap(&value_, 0, 0)原子交换函数,线程安全  //参数为  (type *ptr,type oldvalue, type newvalue)  //如果*ptr==oldvalue,则返回odlvalue,并将*ptr=newvalue  //否则,不会设置*ptr=newvalue,但也会返回*ptr    return __sync_val_compare_and_swap(&value_, 0, 0);  }//先获取,在+x  T getAndAdd(T x)  {  //__sync_fetch_and_add(&value_, x)原子增加函数,线程安全    return __sync_fetch_and_add(&value_, x);  }//先+,后获取  T addAndGet(T x)  {    return getAndAdd(x) + x;  }//将值+1再获取  T incrementAndGet()  {    return addAndGet(1);  }//-1再获取  T decrementAndGet()  {    return addAndGet(-1);  }//增加x  void add(T x)  {    getAndAdd(x);  }//+1  void increment()  {    incrementAndGet();  }//-1  void decrement()  {    decrementAndGet();  }//先获取再赋值  T getAndSet(T newValue)  {    //__sync_lock_test_and_set(&value_, newValue)原子赋值操作    return __sync_lock_test_and_set(&value_, newValue);  }//volatile的做用://防止编译器对代码进行优化,系统总是从内存中读取该变量的值 private:  volatile T value_;};}//对实例化模板   32位typedef detail::AtomicIntegerT<int32_t> AtomicInt32;//64位typedef detail::AtomicIntegerT<int64_t> AtomicInt64;}
这是一个模板类,只有一个字段value_,比较简单,__sync_val_compare_and_swap(type *ptr,type oldvalue, type newvalue),如果*ptr==oldvalue,则返回odlvalue,并将*ptr=newvalue,否则,不会设置*ptr=newvalue,但也会返回*ptr,相当于原子获取操作。__sync_fetch_and_add()就是原子增加操作,__sync_lock_test_and_set()是原子赋值操作。然后其余的成员函数就是对变量的加减,获取,设置操作。volatile声明的变量,系统总是重新从他所在的内存读取,而不是使用保存在寄存器中的备份。