一、前言
1、最早我是从微信公众号看到这篇文章的,了解到开源项目ananas(A C++11/golang protobuf RPC framework)实现了Linux高性能网络库和rpc功能,里面的核心是重写了C++11 future的用法。微信文章的链接是:
https://mp.weixin.qq.com/s/hurLTscQv0eQHXqCmtKaJQ
ananas的作者是Bert Young,他的github地址是https://github.com/loveyacper
ananas-rpc及promise/future技术,QQ交流群号:784231426
2、promise/future相关源码
https://github.com/loveyacper/ananas -- ananas项目源码,下载解压之后把文件夹名称ananas-master改成ananas再编译,否则会找不到路径
https://github.com/loveyacper/ananas/tree/master/future -- ananas的核心源码是future
https://github.com/facebook/folly/tree/master/folly/futures -- folly future,Folly: Facebook Open-source Library
腾讯的tars也有promise/future的实现:
https://github.com/TarsCloud/TarsCpp/tree/master/servant/promise
boost也有实现future,源码位于:
https://sourceforge.net/projects/boost/files/boost/ -- src
/boost_1_68_0/boost/thread/futures/*.*
/boost_1_68_0/boost/thread/future.hpp
https://github.com/chenshuo/muduo -- muduo项目源码,ananas网络库和它类似,one loop per thread+threadpool
https://github.com/netty/netty -- netty项目源码,ananas的EventLoopGroup参考了java netty的实现
https://github.com/netty/netty/tree/3.10
Netty 是由 JBOSS 提供的一个开源的 java 网络编程框架,主要是对 java 的 nio 包进行了再次封装。Netty 比 java 原生的nio 包提供了更加强大、稳定的功能和易于使用的 api。 netty 的作者是 Trustin Lee,这是一个韩国人,他还开发了另外一个著名的网络编程框架,mina。二者在很多方面都十分相似,它们的线程模型也是基本一致 。不过 netty 社区的活跃程度要 mina 高得多。
Netty 3.x 目前企业使用最多的版本,最为稳定。例如dubbo使用的就是3.x版本
Netty 4.x 引入了内存池等重大特性,可以有效的降低GC负载,rocketmq使用的就是4.x
Netty 5.x 已经被废弃了,具体可参见 https://github.com/netty/netty/issues/4466
在并发编程中,我们通常会用到一组非阻塞的模型:Promise,Future 和 Callback。其中的 Future 表示一个可能还没有实际完成的异步任务的结果,针对这个结果可以添加 Callback 以便在任务执行成功或失败后做出对应的操作,而 Promise 交由任务执行者,任务执行者通过 Promise 可以标记任务完成或者失败。 可以说这一套模型是很多异步非阻塞架构的基础。Netty 4中正提供了这种Future/Promise异步模型。Netty文档说明Netty的网络操作都是异步的, 在源码上大量使用了Future/Promise模型,在Netty里面也是这样定义的:
Future接口定义了isSuccess(),isCancellable(),cause(),这些判断异步执行状态的方法。(read-only)
Promise接口在extneds future的基础上增加了setSuccess(), setFailure()这些方法。(writable)
promise/future是一个非常重要的异步编程模型,它可以让我们摆脱传统的回调陷阱,
从而使用更加优雅、清晰的方式进行异步编程。标准c++11中已经开始支持std::future/std::promise,
那么为什么Facebook folly还要提供自己的一套实现呢?原因是c++标准提供的future过于简单,
而folly的实现中最大的改进就是可以为future添加回调函数(比如then),这样可以方便的
链式调用,从而写出更加优雅、间接的代码,然后,改进还不仅仅如此。
一个 Future 就是说“将来”你需要某些东西(一般就是一个网络请求的结果),但是你现在就要发起这样的请求,并且这个请求会异步执行。或者换一个说法,你需要在后台执行一个异步请求。
Future/Promise 模式在多种语言都有对应的实现。最典型的 C++11 标准库中就提供了 future/promise,另外,再比如 ES2015 就有 Promise 和 async-await,Scala 也内置了 Future。
Future与Promise其实二个完全不同的东西:
Future:用来表示一个尚未有结果的对象,而产生这个结果的行为是异步操作;
Promise:Future对象可以使用Promise对象来创建(getFuture),创建后,Promise对象保存的值可以被Future对象读取,同时将二个对象共享状态关联起来。可以认为Promise为Future结果同步提供了一种手段;
简而言之就是:他们提供了一套非阻塞并行操作的处理方案,当然,你可以阻塞操作来等待Future的结果返回。
3、相关的知识链接
CentOS 7安装cmake 2.8.12.2,请重点关注CMake Practice教程
我个人的protobuf-3.5.2实践:安装与测试 -- ananas依赖protobuf协议,请安装
《Linux多线程服务端编程:使用muduo C++ 网络库》学习笔记,★firecat推荐★
十大必掌握C++ 11新特性(std)
深入理解C++11(std)
C++11并发编程(std)
C++11 多线程 future/promise简介(std,boost)
C++ 异步调用利器future/promise实现原理(std,boost)
folly教程系列之:future/promise(facebook)
Facebook为C++ 11带来了健壮且强大的Folly Futures库(facebook)
Facebook 的 C++ 11 组件库 Folly Futures(facebook)
Tars框架Future/Promise使用
Future/Promise
Herb Sutter写的C++ future提案
二、future是annans的核心所在,更详细的介绍请见:
https://github.com/loveyacper/ananas/blob/master/future/README.md
基于future和协程的redis客户端
C++11 ananas库系列(一) Future使用篇
三、转载微信文章如下:
ananas是一个C++11编写的基础库,包括了后台开发常用的一些功能:udp-tcp, epoll-kqueue的网络库封装,python-style的协程,易用的timer,多线程logger,threadPool,tls,unittest,google-protobuf-rpc,以及强大的future-promise。
1.ananas来由
接触C++11也有2-3年了,个人在两个月前决定对后台常用代码做一个整理,开始编写ananas。也非常巧合,大约10天后也就是2016.12月中旬,我和几位同事合作开发一款简易的moba小游戏,使用帧同步,服务器只需要维护简单的房间逻辑和连接管理,做好分帧消息用timer下发即可。鉴于是快速demo开发,客户端不打算接公司组件,因此服务器也不使用tsf4g。只花了半个下午就利用ananas+protobuf与客户端初步通信成功,并在年前顺利的向leader们完成了游戏展示,我也决定继续开发维护ananas。本文先介绍一下ananas future的使用。
2.Future简介
在使用C++11之后,大家应该发现标准库已经实现了promise / future。但是,稍稍了解后就会发现,这份代码像是为了完成KPI而加入的,其鸡肋的程度不亚于当年的std::auto_ptr。是的,你只能对future轮询或者阻塞等待,在关注性能的代码中是无法使用的。因此Herb Sutter等人提出了新的future提案:点我打开C++ future提案ananas future实现了该提案的所有功能,甚至更多(when-N, 以及非常重要的timeout支持)。另外底层基础设施主要借鉴folly future,它帮我解决了C++模板的各种晦涩难用的语法问题。在下一篇源码实现篇再详解。有关Folly future简介可以看这篇文章:facebook folly future库介绍