详谈C++11新特性之future及开源项目ananas(folly,std c++11和ananas的future各自的区别是?)(一)

简介: 详谈C++11新特性之future及开源项目ananas(folly,std c++11和ananas的future各自的区别是?)

一、前言


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


https://www.boost.org/doc/libs/1_68_0/doc/html/thread/synchronization.html#thread.synchronization.futures -- doc


/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库介绍




相关文章
|
12天前
|
存储 对象存储 C++
C++ 中 std::array<int, array_size> 与 std::vector<int> 的深入对比
本文深入对比了 C++ 标准库中的 `std::array` 和 `std::vector`,从内存管理、性能、功能特性、使用场景等方面详细分析了两者的差异。`std::array` 适合固定大小的数据和高性能需求,而 `std::vector` 则提供了动态调整大小的灵活性,适用于数据量不确定或需要频繁操作的场景。选择合适的容器可以提高代码的效率和可靠性。
33 0
|
2月前
|
存储 安全 编译器
在 C++中,引用和指针的区别
在C++中,引用和指针都是用于间接访问对象的工具,但它们有显著区别。引用是对象的别名,必须在定义时初始化且不可重新绑定;指针是一个变量,可以指向不同对象,也可为空。引用更安全,指针更灵活。
|
2月前
|
C语言 C++
C 语言的关键字 static 和 C++ 的关键字 static 有什么区别
在C语言中,`static`关键字主要用于变量声明,使得该变量的作用域被限制在其被声明的函数内部,且在整个程序运行期间保留其值。而在C++中,除了继承了C的特性外,`static`还可以用于类成员,使该成员被所有类实例共享,同时在类外进行初始化。这使得C++中的`static`具有更广泛的应用场景,不仅限于控制变量的作用域和生存期。
69 10
|
2月前
|
C语言 C++
实现两个变量值的互换[C语言和C++的区别]
实现两个变量值的互换[C语言和C++的区别]
29 0
|
3月前
|
安全 C++
C++: std::once_flag 和 std::call_once
`std::once_flag` 和 `std::call_once` 是 C++11 引入的同步原语,确保某个函数在多线程环境中仅执行一次。
|
4月前
|
存储 程序员 C++
【C++小知识】基于范围的for循环(C++11)
【C++小知识】基于范围的for循环(C++11)
|
4月前
|
编译器 C语言 C++
【C++关键字】指针空值nullptr(C++11)
【C++关键字】指针空值nullptr(C++11)
|
1月前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
51 2
|
1月前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
108 5
|
1月前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
98 4