原子操作与原子整数
前言:
C/C++中数值操作,如自加(n++)自减(n–-)及赋值(n=2)操作都不是原子操作,如果是多线程程序需要使用全局计数器,程序就需要使用锁或者互斥量,对于较高并发的程序,会造成一定的性能瓶颈。
为了提高赋值操作的效率,gcc提供了一组api,通过汇编级别的代码来保证赋值类操作的原子性,相对于涉及到操作系统系统调用和应用层同步的锁和互斥量,这组api的效率要高很多。
类名:muduo::detail::AtomicIntegerT
功能:实现对数据类型的原子操作
知识点:
volatile关键字
多任务环境下各任务间共享的标志应该加volatile,其可以防止优化编译器把变量从内存装入CPU寄存器中,避免线程一个使用内存中的变量,一个使用寄存器中的变量,这会造成程序的错误执行
用途:
可用于多线程编程中共享标志的使用,也可用于其他原子操作
1) 中断服务程序中修改的供其它程序检测的变量需要加volatile;
2) 多任务环境下各任务间共享的标志应该加volatile;
3) 存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义;
源码及注释
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.
//
// Author: Shuo Chen (chenshuo at chenshuo dot com)
#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:
//构造函数,初始化value
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;
// }
//
//{ if (*ptr == oldval) { *ptr = newval; } return oldval; }
//返回0
T get()
{
// in gcc >= 4.7: __atomic_load_n(&value_, __ATOMIC_SEQ_CST)
return __sync_val_compare_and_swap(&value_, 0, 0);
}
//返回value更新前的值,即返回value
T getAndAdd(T x)
{
// in gcc >= 4.7: __atomic_fetch_add(&value_, x, __ATOMIC_SEQ_CST)
return __sync_fetch_and_add(&value_, x);
}
//value 加 x
T addAndGet(T x)
{
return getAndAdd(x) + x;
}
//value 加 1
T incrementAndGet()
{
return addAndGet(1);
}
//value 减 1
T decrementAndGet()
{
return addAndGet(-1);
}
//value 加 x
void add(T x)
{
getAndAdd(x);
}
//value 加 1
void increment()
{
incrementAndGet();
}
//value 加 1
void decrement()
{
decrementAndGet();
}
//将value设置为newValie,返回操作前value的值
T getAndSet(T newValue)
{
// in gcc >= 4.7: __atomic_exchange_n(&value, newValue, __ATOMIC_SEQ_CST)
return __sync_lock_test_and_set(&value_, newValue);
}
private:
volatile T value_;
};
}
typedef detail::AtomicIntegerT<int32_t> AtomicInt32;//声明32位整数
typedef detail::AtomicIntegerT<int64_t> AtomicInt64;//声明64位整数
}
#endif // MUDUO_BASE_ATOMIC_H