38|异步处理:Future是什么?它和async/await是什么关系?
该思维导图由 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-086 - 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-012 - 罗杰代码中的 toml::from_str 编译不过,但在 play.rust-lang.org 中竟然可以编译通过,很神奇,我在本地添加了 toml 库,并且 use toml 之后,代码就可以正常运行了。
作者回复: playground 把常见的 crate 都添加了
2021-11-26 - ELSE有个疑问,像这样的语句,同步和异步有什么区别吗 let listener = TcpListener::bind(addr).await?;2022-07-1312
- zxk这是由于 MutexGuard 没有实现 Send trait。 对于 MutexGuard 为什么不实现 Send 的一点思考,不知道是否理解正确,望老师指点下。 标准库的 MutexGuard 主要是针对线程的,一个线程通过 lock 获取到锁后独占该临界区的资源。假设允许 MutexGuard 跨越 await,那么 MutexGuard 就有可能随着 Future 跑到其他线程上执行,那就破坏了之前的线程独占该临界区的语义了。2022-07-102
- 罗杰今天的内容要好好消化一下…2021-11-261
- Geek_91aad0真的经典,反复做笔记反复理解,配合future的源码才完全看懂!真的是技术深度极高!2024-03-18归属地:北京
- 鱼丸粗面mutexGuard的drop方法里有释放锁的功能,它销毁时会释放锁,把它发出去会造成同步语义的破坏。比如guard已经被销毁而当前线程仍然在安全区域修改被保护的数据2022-10-06归属地:广东
- RAY_CCW😝😝😝tyr老师,想问一下,其实Rust executor的Reactor 模式,本质是也是用了类似于事件驱动的异步方式来实现?因为近年都在写go,看到这个想起来以前写Python时候的gevent的感觉了。2022-03-20
- ...zzZrust future中的task和executor能不能类比于go MPG模型中的G和P?2022-02-22