muduo网络库源码学习————原子性操作Atomic.h
来源:互联网 发布:展示实时数据 时间轴 编辑:程序博客网 时间:2024/05/21 06:26
原子性操作可以做到比互斥锁更小的开销,在多线程编程中原子性操作是非常有用的。Atomic.h文件位于muduo/base下,代码如下:
// 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: 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; // } T get() {//原子性比较还有设置操作 return __sync_val_compare_and_swap(&value_, 0, 0);//判断value的值是否为零,如果为0则赋值0 //返回的是未赋值之前的值,其实就是获取value的值 } T getAndAdd(T x) {//先获取然后执行加的操作,返回的是未修改的值 return __sync_fetch_and_add(&value_, x); } T addAndGet(T x) {//先加然后获取 return getAndAdd(x) + x;//这里是调用getAndAdd函数,返回之后再加上x } T incrementAndGet() {//自加1 return addAndGet(1); } T decrementAndGet() {//自减1 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_;//volatile关键字确保指令不会因编译器的优化而省略(防止编译器对代码进行优化) //每次都从内存读取数据而不是使用保存在寄存器中的备份 //是为了避免其他线程已经将该值修改};}//两个实例化,32位和64位的原子性操作typedef detail::AtomicIntegerT<int32_t> AtomicInt32;typedef detail::AtomicIntegerT<int64_t> AtomicInt64;}#endif // MUDUO_BASE_ATOMIC_H
其测试代码为Atomic_unittest.cc主要是进行一些简单的判别操作:
#include <muduo/base/Atomic.h>#include <assert.h>//原子性操作的测试函数int main(){ {//64位的原子性操作 muduo::AtomicInt64 a0; //断言测试一个条件并可能使程序终止 assert(a0.get() == 0);//首先肯定会被置为0 assert(a0.getAndAdd(1) == 0);//加1,先获取然后加,还是0 assert(a0.get() == 1);//此时变为1 assert(a0.addAndGet(2) == 3);//先加然后获取,所以是3 assert(a0.get() == 3); assert(a0.incrementAndGet() == 4);//先加然后获取 assert(a0.get() == 4); a0.increment(); assert(a0.get() == 5); assert(a0.addAndGet(-3) == 2); assert(a0.getAndSet(100) == 2); assert(a0.get() == 100); } {//32位的原子性操作 muduo::AtomicInt32 a1; assert(a1.get() == 0); assert(a1.getAndAdd(1) == 0); assert(a1.get() == 1); assert(a1.addAndGet(2) == 3); assert(a1.get() == 3); assert(a1.incrementAndGet() == 4); assert(a1.get() == 4); a1.increment(); assert(a1.get() == 5); assert(a1.addAndGet(-3) == 2); assert(a1.getAndSet(100) == 2); assert(a1.get() == 100); }}
单独编译后运行结果如下,因为断定都是正确的,所以执行不会有任何的结果
1 0
- muduo网络库源码学习————原子性操作Atomic.h
- [Muduo网络库源码分析] (1) base/Atomic.h_原子操作与原子整数
- muduo网络库学习笔记(2):原子性操作
- Concurrent——Atomic原子操作类
- muduo网络库源码学习————互斥锁
- muduo源码学习(3)-原子操作
- muduo库源码学习(base)Atomic
- muduo网络库源码学习————Timestamp.cc
- muduo网络库源码学习————Exception类
- muduo网络库源码学习————线程类
- muduo网络库源码学习————条件变量
- muduo网络库源码学习————无界队列和有界队列
- muduo网络库源码学习————线程池实现
- muduo网络库源码学习————线程安全
- muduo网络库源码学习————线程特定数据
- muduo网络库源码学习————线程本地单例类封装
- muduo网络库源码学习————日志类封装
- muduo网络库源码学习————日志滚动
- 库编译
- HDU-1863 畅通工程
- 北京-IT技术狗-顾名思义 解释一下当时随手写下这个名字
- Codeforces Round #201 (Div. 2) 347C Alice and Bob(脑洞)
- 有向图中单个源点到终点的最短路径--Dijkstra算法与实现
- muduo网络库源码学习————原子性操作Atomic.h
- 九度OJ 题目1130:日志排序
- JSP页面的五种跳转方法
- iOS 代理 协议
- swift学习之路-数组
- xamarin ios XibFree LinearLayout
- Nginx配置Https
- QT的信号与槽机制介绍
- POJ 3522 Slim Span(最小生成树)