详谈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库介绍




相关文章
|
6月前
|
算法 Java 数据库连接
Java 与 C++ 区别深入剖析及应用实例详解
本文深入剖析了Java和C++两种编程语言的区别,从编译与执行机制、面向对象特性、数据类型与变量、内存管理、异常处理等方面进行对比,并结合游戏开发、企业级应用开发、操作系统与嵌入式开发等实际场景分析其特点。Java以跨平台性强、自动内存管理著称,适合企业级应用;C++则因高性能和对硬件的直接访问能力,在游戏引擎和嵌入式系统中占据优势。开发者可根据项目需求选择合适语言,提升开发效率与软件质量。附面试资料链接:[点此获取](https://pan.quark.cn/s/4459235fee85)。
636 0
|
8月前
|
编译器 C++ 容器
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
C++11为C++带来了革命性变化,引入了列表初始化、右值引用、移动语义、类的新默认成员函数和lambda表达式等特性。列表初始化统一了对象初始化方式,initializer_list简化了容器多元素初始化;右值引用和移动语义优化了资源管理,减少拷贝开销;类新增移动构造和移动赋值函数提升性能;lambda表达式提供匿名函数对象,增强代码简洁性和灵活性。这些特性共同推动了现代C++编程的发展,提升了开发效率与程序性能。
350 12
|
10月前
|
存储 机器学习/深度学习 编译器
【C++终极篇】C++11:编程新纪元的神秘力量揭秘
【C++终极篇】C++11:编程新纪元的神秘力量揭秘
|
存储 安全 编译器
在 C++中,引用和指针的区别
在C++中,引用和指针都是用于间接访问对象的工具,但它们有显著区别。引用是对象的别名,必须在定义时初始化且不可重新绑定;指针是一个变量,可以指向不同对象,也可为空。引用更安全,指针更灵活。
|
存储 对象存储 C++
C++ 中 std::array<int, array_size> 与 std::vector<int> 的深入对比
本文深入对比了 C++ 标准库中的 `std::array` 和 `std::vector`,从内存管理、性能、功能特性、使用场景等方面详细分析了两者的差异。`std::array` 适合固定大小的数据和高性能需求,而 `std::vector` 则提供了动态调整大小的灵活性,适用于数据量不确定或需要频繁操作的场景。选择合适的容器可以提高代码的效率和可靠性。
|
C语言 C++
C 语言的关键字 static 和 C++ 的关键字 static 有什么区别
在C语言中,`static`关键字主要用于变量声明,使得该变量的作用域被限制在其被声明的函数内部,且在整个程序运行期间保留其值。而在C++中,除了继承了C的特性外,`static`还可以用于类成员,使该成员被所有类实例共享,同时在类外进行初始化。这使得C++中的`static`具有更广泛的应用场景,不仅限于控制变量的作用域和生存期。
343 10
|
安全 C++
C++: std::once_flag 和 std::call_once
`std::once_flag` 和 `std::call_once` 是 C++11 引入的同步原语,确保某个函数在多线程环境中仅执行一次。
|
C语言 C++
实现两个变量值的互换[C语言和C++的区别]
实现两个变量值的互换[C语言和C++的区别]
202 0
|
10月前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
6月前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
192 0