关于 Rust 异步(无栈协程)的相关疑问

这是一个记录问题+求助的文章。

关于 waker 与运行时的合作方式

我肤浅地学习了 Rust 异步底层实现原理,关于 Future、waker 和运行时等。关于 waker 我有三点猜测:

  1. waker 是由实现执行器的人提供的
  2. 在执行器中会调用 epoll_wait,epoll 返回 fd,执行器找到对应的 waker,调用 wake() 通知任务继续
  3. 最底层的 future 是人工实现的,而不是编译器生成的,future 内部调用 cx.waker() 获取 waker,在任务无法继续执行时,把 waker 注册到特定运行时的注册表中,与 fd 关联。调用 epoll_ctl 注册 fd。

我想知道既然 Future 要把 waker 注册给运行时,使得运行时知道这个 waker 是与某个 fd 关联的。那么实现这个 Future 的 poll 方法时,就应该知道这个 Future 将来会被哪个运行时调用,从而知道怎么给这个运行时注册 waker。但真的是这样吗,这样岂不就决定了这个 Future 不能被其他运行时调用了?或者说 Rust 生态中,你要实现一个异步库,就必须得选定一个运行时,干脆用运行时提供的底层 Future,自己只是实现一些上层的应用逻辑?

关于无栈协程的传染性

这种说法的来源是哪里?网上有人说无栈协程以"函数返回"的方式完成从协程到主协程(或者说正常线程执行流)的切换,所以协程执行过程中创造的栈没有被保存,最终导致传染性。而传染性是指调用 await 的地方,必须在 async,而 async 又必须以 await 的形式调用,这样传入到最外层也都是 async/await 了。

但是"必须在 async 里调用 await"不只是一个编译器规定吗,如果编译器没这么规定就没有传染性了?一定有人说,编译器之所以这么规定是因为"无栈"的设计,这么规定是必然的。但 async 函数实际上是 impl Future 类型,对 Future 的 poll 是没有传染性的(可以在一般的非 async 函数中 poll),而 Future poll 的过程也会在不同的地方中断,其局部变量等上下文不也保存的好好的?无栈只是指局部变量不以栈的形式保存,也不以切换上下文的形式切换。

我没用过太多 Rust 异步特性,用的也都是在很高层次上使用。我觉得为了理解上述问题可能需要阅读一些异步库,甚至自己写一个小的 tokio。(阅读 tokio 的源码是不是太难了,有没有 mini-tokio 啊)

BTW,我是不是不应该指望 csdn 的环境能有人回答我的问题呀hh,希望有大佬能参与讨论

相关推荐
维吉斯蔡4 小时前
【VS Code / Cursor】文件夹右键快捷打开与文件类型自动关联
开发语言·程序人生·学习方法
前端工作日常5 小时前
我学习到的Java 的 Service 分层:itf 和 impl 到底是什么?
java·后端
前端工作日常6 小时前
我学习到的JIT即时编译与机器码缓存失效
java·后端
犀利豆6 小时前
Claude Code Tools 研究系列(三)ExitPlanMode
人工智能·后端
luj_17686 小时前
星火科技助力边远地区防病攻坚
c语言·开发语言·c++·经验分享·算法
always_TT6 小时前
【Python 日志记录:logging 模块入门】
开发语言·python·php
星栈7 小时前
oh-my-pi工程级AI编码工使用体验
人工智能·后端·agent
xcLeigh7 小时前
Go入门:变量声明的五种方式详解
java·开发语言·golang
zmzb01037 小时前
C++课后习题训练记录Day175
开发语言·c++
花褪残红青杏小7 小时前
Rust图像处理第24节- 噪声模型 + 中心极限定理:椒盐噪声 + CLT 可视化
rust·webassembly·图形学