零成本异步 I/O (下)

2024-06-23 00:48
文章标签 异步 成本

本文主要是介绍零成本异步 I/O (下),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这是 Withoutboats 在 2019 年 3 月的 Rust Latam 上所做报告的一个整理。这个报告主要介绍他参与开发了一年半的语言特性,包括 Rust 异步 I/O 的发展历程,以及目前已经稳定的零成本抽象的async/await 语法的关键实现原理。

Withoutboats 是就职于 Mozilla 的一名研究员,主要从事 Rust 语言开发。他开发的这个语言特性叫做 async/await,这可能是本年度我们在 Rust 语言上做的最重要的事。这解决了困扰我们很久的问题,即我们如何能在 Rust 中拥有零成本抽象的异步IO。

注:因讲稿篇幅较长,所以分成上下两部分;因个人水平有限,翻译和整理难免有错误或疏漏之处,欢迎读者批评指正。

基于轮询的解决方案

// 基于轮询的 Future

trait Future {
type Output;
fn poll(&mut self, waker: &Waker)
-> Poll<Self::Output>;
}

enum Poll<T> {
Ready(T),
Pending,
}

这个非常出色的基于轮询的新方案——我们编写了这个模型,我归功于 Alex 和 Aaron Turon,是他们提出了这个想法——不是由 Future 来调度回调函数,而是由我们去轮询 Future,所以还有另一个被称为执行器(executor)的组件,它负责实际运行 Future ;执行器的工作就是轮询 Future ,而 Future 可能返回“尚未准备就绪(Pending)”,也可能被解决就返回“已就绪(Ready)”。

该模型有很多优点。其中一个优点是,你可以非常容易地取消 Future ,因为取消 Future 只需要停止持有 Future。而如果采用基于回调的方法,要通过调度来取消并使其停止就没这么容易了。

同时它还能够使我们在程序的不同部分之间建立真正清晰的抽象边界,大多数 Future 库都带有事件循环(event loop),这也是调度你的 Future 执行 I/O 的方法,但你实际上对此没有任何控制权。而在 Rust 中,各组件之间的边界非常整洁,执行器(executor)负责调度你的 Future ,反应器(reactor)处理所有的 I/O ,然后是你的实际代码。因此最终用户可以自行决定使用什么执行器,使用他们想使用的反应器,从而获得更强的控制力,这在系统编程语言中真的很重要。而此模型最重要的真正优势在于,它使我们能够以一种真正零成本的完美方式实现这种状态机式的 Future 。也就是当你编写的 Future 代码被编译成实际的本地(native)代码时,它就像一个状态机;在该状态机中,每次 I/O 的暂停点都有一个变体(variant),而每个变体都保存了恢复执行所需的状态。这表示为一个枚举(enum)结构,即一个包含变体判别式及所有可能状态的联合体(union)。

译者注:报告视频中的幻灯片比较模糊,我对其进行了重绘与翻译,下同。

上面的幻灯片尽可能直观地表示了这个状态机模型。可以看到,你执行了两个 I/O 事件,所以它有这几个状态。对于每个状态它都提供了所需的内存空间,足够你在 I/O 事件后恢复执行。

整个 Future 只需要一次堆内存分配,其大小就是你将这个状态机分配到堆中的大小,并且没有额外的开销。你不需要装箱、回调之类的东西,只有真正零成本的完美模型。这些概念对于很多人来说比较难于理解,所以这是我力求做到最好的幻灯片,直观地呈现这个过程中发生了什么:你创建一个 Future,它被分配到某个内存中特定的位置,然后你可以在执行器(executor)中启动它。

执行器会轮询 Future,直到最终 Future 需要执行某种 I/O 。

这篇关于零成本异步 I/O (下)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1085871

相关文章

人工和AI大语言模型成本对比 ai语音模型

这里既有AI,又有生活大道理,无数渺小的思考填满了一生。 上一专题搭建了一套GMM-HMM系统,来识别连续0123456789的英文语音。 但若不是仅针对数字,而是所有普通词汇,可能达到十几万个词,解码过程将非常复杂,识别结果组合太多,识别结果不会理想。因此只有声学模型是完全不够的,需要引入语言模型来约束识别结果。让“今天天气很好”的概率高于“今天天汽很好”的概率,得到声学模型概率高,又符合表达

Rust:Future、async 异步代码机制示例与分析

0. 异步、并发、并行、进程、协程概念梳理 Rust 的异步机制不是多线程或多进程,而是基于协程(或称为轻量级线程、微线程)的模型,这些协程可以在单个线程内并发执行。这种模型允许在单个线程中通过非阻塞的方式处理多个任务,从而实现高效的并发。 关于“并发”和“并行”的区别,这是两个经常被提及但含义不同的概念: 并发(Concurrency):指的是同时处理多个任务的能力,这些任务可能在同一时

玩转Web之easyui(二)-----easy ui 异步加载生成树节点(Tree),点击树生成tab(选项卡)

关于easy ui 异步加载生成树及点击树生成选项卡,这里直接给出代码,重点部分代码中均有注释 前台: $('#tree').tree({ url: '../servlet/School_Tree?id=-1', //向后台传送id,获取根节点lines:true,onBeforeExpand:function(node,param){ $('#tree').tree('options'

【Python】 异步编程

【Python】 异步编程 1. nest_asyncio基础定义2. nest_asyncio 举例实现基本用法 1. nest_asyncio基础定义 nest_asyncio.apply() 是 Python 编程中与异步编程相关的一个调用,它用于解决某些特定环境下的异步编程问题。下面是对这个调用的详细解释: nest_asyncio 模块:这是一个第三方库,它提供

AJAX:如何编写一个关于AJAX的Hello World?(ajax发送异步请求(四步操作))

用到的一个Servlet类: package cn.edu.web.servlet;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;impor

iOS Runloop面试题(什么是异步绘制?)

什么是异步绘制? 异步绘制,就是可以在子线程把需要绘制的图形,提前在子线程处理好。将准备好的图像数据直接返给主线程使用,这样可以降低主线程的压力。 异步绘制的过程 要通过系统的 [view.delegate displayLayer:] 这个入口来实现异步绘制。 代理负责生成对应的 Bitmap设置该 Bitmap 为 layer.contents 属性的值。

协程: Flow 异步流 /

以异步方式返回多个返回值的方案: 在 Kotlin 协程 Coroutine 中 , 使用 suspend 挂起函数 以异步的方式 返回单个返回值肯定可以实现 , 如果要 以异步的方式 返回多个元素的返回值 , 可以使用如下方案 : 集合序列Suspend 挂起函数Flow 异步流 同步调用返回多个值的弊端   鸣谢: mAndroid面试题之Kotlin异步流、冷流Flow

极客新闻——13、美团到餐研发团队资源成本优化实践

本文笔记全部来自《极客新闻》——新鲜的技术资讯、权威的趋势剖析、别样的技术洞察 工程师主要面对的是技术挑战,更关注技术层面的目标。研发团队的管理者则会把实现项目成果和业务需求作为核心目标。在实际项目中,研发团队所需资源(比如物理机器、内存、硬盘、网络带宽等)的成本,很容易被忽略,或者在很晚才考虑。 最近,美团技术团队分享了美团到餐研发团队的资源成本优化实践。主要包括以下5点: 1、确定方

VUE\JS处理在循环中异步和同步执行的问题

业务场景: 1、有一个组别集合,每一个小组别对象里面有一个数据集合,需要循环去校验每个不同组里的数据(不同组合因为一些特殊属性不能合并到一个组里),全都符合就通过验证,去处理后续业务。 2、现在,在校验规则方法里对一个集合里的每一条数据进行强校验和弱校验,弱校验需要在提升框放入确定的操作按钮,允许通过,再循环到下一条数据的验证。 代码分析 1、涉及到组别集合的循环、组别内部数据的循环,循环套

【Rust日报】 2019-05-29:异步await语法最终确定

orkhon: 机器学习框架和运行时 #Python #ml Orkhon是用于机器学习的Rust框架,用于运行/使用用Python编写的推理/预测代码,冻结模型和处理未知(unseen)数据。 orkhon 「异步系列文章」Part 2: Async/Await语法之外的挑战 : 取消(Cancellation) #async #await 在这篇文章里,作者讨论了如果在应用中取消正