Rust语言:异步编程,一个小故事带你入门
Posted 暗黑程序员
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Rust语言:异步编程,一个小故事带你入门相关的知识,希望对你有一定的参考价值。
有这么一个有趣的故事:某家包子铺刚开业,生意十分火爆,很多人在店外排队等候购买。老板发现靠自己一人很难满足这么多人的消费,所以就又招了几个服务员,解决了排队时间过长的问题。随着互联网的兴起,老板购买了一个小程序系统,顾客可以提前下单,包子熟了自动发货到顾客的单位。
通过这个小故事我们发现,最初的经营方式是效率很低下,属于单生产者 - 单消费者模式。随后,更改为多生产者 - 单消费者模式,效率有所提升,可是顾客仍然需要排队等候购买。后来老板的新系统上线,才最终彻底解决了生产者和消费者等待的问题。
这就是我将要和大家分享的Rust异步编程,同步非阻塞,即代码书写是同步的,内部执行逻辑是非阻塞的。
什么是异步编程?
异步,是相对于同步而言的。同步,是指大家按照次序一个个来,上个顾客付完钱拿到了包子才能轮到下一位。而异步,就是上一个顾客付完钱拿到订单票号就让出来给下一位顾客了,等到包子熟了,自会按照订单票号呼叫到指定的人来拿包子即可。
Rust异步编程,使用Future来表示订单票号,使用Task来表示订单任务,使用Executor来表示包子铺厨子,使用Poll来表示橱子做包子用什么馅。
再描述的形象点,收银员处理了10位顾客的购买请求,打印了10张订单票号Future,将这10张订单票号组合成一个任务Task,交给了里面的师傅Executor来蒸包子,橱子看到Poll后大笑一声知道了,开始干活了。
Future详解
Future是一种订单票号,该票号指定了最终得到的是什么物品,比如上文的包子。
官方核心代码定义如下:
如果要创建一个Future,必须实现poll,告诉橱子用什么馅做食物,还必须指定食物是什么东西Output。
Task详解
Task是一系列Future的叠加。
Future可以是嵌套组合的,也可以是并列组合的。嵌套组合的意思是Future里包含了其他Future,一层层包含下去。并列组合的意思是几个互相独立的Future,合并在一起组合成一个新的Future。
无论如何,最终都是打包成一个可以具体操作的Task任务。
Executor详解
上面以包子、橱子等举例子,只为让大家能更容易的接受Rust复杂的异步实现当中的几大角色。
而真正在一线工厂干活的,是这个底层的Executor,当然也是非常重要的一个角色,内部实现原理还是有点复杂的。
不知道各位是否看过知乎的“深入浅出Rust异步编程”,有些概念比如Waker、Park、Context、Schedulor等等,要搞明白这些概念还是需要花很多时间研读标准库和tokio库的源码。
这里简单的讲下他们各自的作用。
Waker的作用是提供Task切换时上下文现场的保存和还原。
Park的作用是管理当前线程的运行状态。
Context是Waker的封装,提供操作Waker的入口,因为Waker涉及到重新创建的问题。
写在最后
我感觉这个选题有点过大了,很多地方很难通过几百字就能阐述清楚,而且我本人对tokio的runtime源码也没有完成的研究明白,贸然去写内部的原理,可能会“以己昏昏使人昭昭”。
所以,只能从表象上给大家讲一讲大概的原理,浅述一下什么是Rust的异步编程,深感惭愧。
我也希望能够彻底的搞明白tokio的runtime调度原理,在以后有机会更详细的给大家理一理这一块。
以上是关于Rust语言:异步编程,一个小故事带你入门的主要内容,如果未能解决你的问题,请参考以下文章