muduo网络库源码学习————原子性操作Atomic.h
2015-08-28 19:12
204 查看
原子性操作可以做到比互斥锁更小的开销,在多线程编程中原子性操作是非常有用的。Atomic.h文件位于muduo/base下,代码如下:
其测试代码为Atomic_unittest.cc主要是进行一些简单的判别操作:
单独编译后运行结果如下,因为断定都是正确的,所以执行不会有任何的结果
[code]// 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主要是进行一些简单的判别操作:
[code]#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); } }
单独编译后运行结果如下,因为断定都是正确的,所以执行不会有任何的结果
相关文章推荐
- (五) HTTP/2的流量控制
- Nginx HTTP 负载均衡和反向代理
- Http POST 与 Http GET 的区别
- Java网络编程(新IO概述)
- 在iphone、ipad上安装一些常用命令行命令及实时抓取移动设备上的通信包(ADVsock2pipe+Wireshark+nc+tcpdump)
- Apache http Server与Tomcat整合
- iOS开发 - 获取当前网络状态
- Php魔术方法(http://www.cnblogs.com/xiaochaohuashengmi/archive/2011/09/22/2185034.html)
- 深入浅出LSTM神经网络
- Apache Http Server和Tomcat 之区别
- AJAX POST 与 GET 的区别 && HTTP
- 网络拓扑图
- 一个支持tcp多客户端连接的例子,轻松认识linux select函数的基本原理和使用方法
- android 学习笔记 使用HttpClient
- lighttpd源码学习
- 《TCP/IP详解卷1:协议》——第1章:概述(转载)
- 清除网络共享文件夹密码缓存
- muduo网络库源码学习————Timestamp.cc
- http://www.freebuf.com/
- Response.End(); 用HttpContext.Current.ApplicationInstance.CompleteRequest 代替