从 scratch 开始的异步 1:未来到底是什么?| natkr 的漫谈

这是一篇关于如何从“用户视角”使用异步 Rust 以及理解其工作原理的系列文章的第一篇。

  • 需求背景:有很多关于从用户视角使用异步 Rust 的指南,但了解其工作原理及async块的实际意义也很有价值,如理解为何会出现奇怪的固定错误等。
  • 代码示例及解释

    • 展示了基本的异步函数trick_or_treat,引出对async fn与其他fn的差异及作用的疑问。
    • 介绍了Future trait,它定义了可被await的东西,简化后形如SimpleFuture,其poll方法用于询问Future是否可继续,返回Poll::ReadyPoll::Pending
    • 给出了一些简单的Future实现示例,如总是产生随机数的FairDice、永远等待的LookBusy、需要被轮询 10 次才完成的Stubborn以及委托给另一个FutureLoadedDice。还介绍了ready!宏可简化match poll的代码。
    • 展示了如何通过保存共享状态在enum中实现多次await,如FairDicePair。同时提到原始的poll能做async fn无法表达的事情,如构建超时机制Timeout
  • 运行与组合

    • 定义了运行Future的函数run_future,通过不断调用poll直到返回Ready来运行Future,但这样会浪费 CPU 周期。
    • 引入了组合子combinators,将特殊逻辑泛化为新的构建块供async fn复用,如with_timeout函数可对任意Future设置超时。
  • 输入输出:以从 TCP 套接字读取为例,展示了如何创建套接字、连接远程目的地、设置为非阻塞模式、读取消息等操作,通过TcpRead实现SimpleFuture来读取套接字数据。
  • 后续内容预告:文章只讨论了简化的SimpleFuture变体,后续将揭开更多细节,如解决SimpleFuture的浪费问题的唤醒器(waker)将在下一次讨论,且相关内容已更新在https://natkr.com/2025-04-15-async-from-scratch-2/
阅读 34
0 条评论