陈天 · Rust 编程第一课
陈天
Tubi TV 研发副总裁
23195 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 65 讲
基础篇 (21讲)
陈天 · Rust 编程第一课
15
15
1.0x
00:00/00:00
登录|注册

38|异步处理:Future是什么?它和async/await是什么关系?

TCP服务器示例
Reactor pattern
调度器
Poll
poll()方法
Output
Promise / Future / Goroutine / Erlang process
在线程和异步任务间做同步时
异步代码中使用Mutex时
处理计算密集型任务时
如何用Future做异步处理
executor
Future的结构
大量IO操作导致CPU闲置
CPU算力和IO速度之间的矛盾
语法糖
await触发任务并发执行
async定义了可以并发执行的任务
Promise的状态
未来的某个时刻才能得到的结果的值
线程中的并发任务
进程中的并发任务
节点上的并发任务
分布式系统中的并发任务
思考题
使用Future的注意事项
深入了解
为什么需要Future?
async/await
Rust的Future和JavaScript的Promise
产生和运行并发任务的手段
异步处理:Future是什么?它和async/await是什么关系?

该思维导图由 AI 生成,仅供参考

你好,我是陈天。
通过前几讲的学习,我们对并发处理,尤其是常用的并发原语,有了一个比较清晰的认识。并发原语是并发任务之间同步的手段,今天我们要学习的 Future 以及在更高层次上处理 Future 的 async/await,是产生和运行并发任务的手段。
不过产生和运行并发任务的手段有很多,async/await 只是其中之一。在一个分布式系统中,并发任务可以运行在系统的某个节点上;在某个节点上,并发任务又可以运行在多个进程中;而在某个进程中,并发任务可以运行在多个线程中;在某个(些)线程上,并发任务可以运行在多个 Promise / Future / Goroutine / Erlang process 这样的协程上。
它们的粒度从大到小如图所示:
在之前的课程里,我们大量应用了线程这种并发工具,在 kv server 的构建过程中,也通过 async/await 用到了 Future 这样的无栈协程。
其实 Rust 的 Future 跟 JavaScript 的 Promise 非常类似。
如果你熟悉 JavaScript,应该熟悉 Promise 的概念,02也简单讲过,它代表了在未来的某个时刻才能得到的结果的值,Promise 一般存在三个状态;
初始状态,Promise 还未运行;
等待(pending)状态,Promise 已运行,但还未结束;
结束状态,Promise 成功解析出一个值,或者执行失败。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

异步处理中的Future是一种并发任务处理的手段,与async/await密切相关。在分布式系统中,异步任务可以在不同节点、进程、线程或协程中执行。Rust的Future类似于JavaScript的Promise,但在主动await后才开始执行。通常,async定义了可并发执行的任务,而await触发任务的并发执行。大多数语言中,包括Rust,async/await都是一种语法糖,使用状态机将Promise/Future进行包装处理。 本文通过实际代码示例和技术原理阐述了Future/async/await的基本概念和使用方法。文章内容涵盖了并发编程中的常见问题和解决方案,对于想要深入了解异步处理和并发编程的读者具有很高的参考价值。文章还介绍了executor和reactor的概念,以及如何使用Future进行异步处理。通过TCP服务器的示例,展示了在Rust下使用异步处理的简单性和灵活性。 在实际应用中,读者需要注意避免在异步任务中处理大量计算密集型的工作,使用Mutex时要注意标准库的MutexGuard无法跨越.await,需要使用对异步友好的Mutex,如tokio::sync::Mutex。此外,为了在线程和异步任务间同步,可以使用channel。 总的来说,本文为读者提供了对并发处理的深入理解和实践指导,使读者能够快速了解Future/async/await的基本原理和使用方法,以及注意事项。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《陈天 · Rust 编程第一课》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(10)

  • 最新
  • 精选
  • Marvichov
    现在一节课需要很久才勉强消化...这课真心值! ``` error: future cannot be sent between threads safely 29 | tokio::spawn(async move { | ^^^^^^^^^^^^ future created by async block is not Send ``` tokio::spawn要求T是Send, 也就是可以cross thread boundary ``` pub fn spawn<T>(task: T) -> JoinHandle<T::Output> where T: Future + Send + 'static, T::Output: Send + 'static, ``` 参见: https://docs.rs/tokio/0.2.18/tokio/fn.spawn.html 对executor了解很少...但从文中的提示 (task stealing, 从其他thread偷task), executor应该有个thread pool可以在不同的thread里面poll future... 至于await里面怎么就有多线程的executor, 还希望老师答疑解惑!

    作者回复: tokio 会在每个 CPU core 上运行一个 OS thread 来处理调度。后面的内容讲到,async 和 await 其实就是语法糖,await 的点在编译时都会编译成状态机的一部分,所以一个内部拥有多个 await 的 async 函数,里面是一个复杂的状态机,按 await 的顺序依次 poll future。在 poll 的时候,如果 pending,executor 会将其挂起。executor 再去取下一个可以执行的 Future。如果没有可执行的 Future,才会去"偷" 别的线程队列中的 Future 执行。

    2021-12-08
    6
  • CyNevis
    标准库的 Mutex 不能跨越 await, 盲猜一手是不是标准库的Mutex实现是依赖线程绑定, 得去看代码是怎么实现的

    作者回复: 很简单,因为标准库的 MutexGuard 不是 Send: https://doc.rust-lang.org/src/std/sync/mutex.rs.html#204,而 tokio 的实现了 Send:https://docs.rs/tokio/latest/tokio/sync/struct.MutexGuard.html。

    2021-12-01
    2
  • 罗杰
    代码中的 toml::from_str 编译不过,但在 play.rust-lang.org 中竟然可以编译通过,很神奇,我在本地添加了 toml 库,并且 use toml 之后,代码就可以正常运行了。

    作者回复: playground 把常见的 crate 都添加了

    2021-11-26
  • ELSE
    有个疑问,像这样的语句,同步和异步有什么区别吗 let listener = TcpListener::bind(addr).await?;
    2022-07-13
    1
    2
  • zxk
    这是由于 MutexGuard 没有实现 Send trait。 对于 MutexGuard 为什么不实现 Send 的一点思考,不知道是否理解正确,望老师指点下。 标准库的 MutexGuard 主要是针对线程的,一个线程通过 lock 获取到锁后独占该临界区的资源。假设允许 MutexGuard 跨越 await,那么 MutexGuard 就有可能随着 Future 跑到其他线程上执行,那就破坏了之前的线程独占该临界区的语义了。
    2022-07-10
    2
  • 罗杰
    今天的内容要好好消化一下…
    2021-11-26
    1
  • Geek_91aad0
    真的经典,反复做笔记反复理解,配合future的源码才完全看懂!真的是技术深度极高!
    2024-03-18归属地:北京
  • 鱼丸粗面
    mutexGuard的drop方法里有释放锁的功能,它销毁时会释放锁,把它发出去会造成同步语义的破坏。比如guard已经被销毁而当前线程仍然在安全区域修改被保护的数据
    2022-10-06归属地:广东
  • RAY_CCW😝😝😝
    tyr老师,想问一下,其实Rust executor的Reactor 模式,本质是也是用了类似于事件驱动的异步方式来实现?因为近年都在写go,看到这个想起来以前写Python时候的gevent的感觉了。
    2022-03-20
  • ...zzZ
    rust future中的task和executor能不能类比于go MPG模型中的G和P?
    2022-02-22
收起评论
显示
设置
留言
10
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部