关于 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,希望有大佬能参与讨论

相关推荐
我是坏垠22 分钟前
Crypto、Cipher与Password:Java加密开发的三个核心概念
java·开发语言·python
white_ant41 分钟前
JDK LTS 版本升级迁移注意事项大全
java·开发语言
Bobolink_1 小时前
跨境业务网络环境评估,“干净、一致、独享”三个关键指标
开发语言·网络·php·跨境网络·网络环境
你怎么知道我是队长1 小时前
JavaScript的变量和数据类型介绍
开发语言·javascript·ecmascript
xingke1 小时前
C 语言多文件编程:(一)头文件、extern、编译链接
c语言·开发语言·多文件
戮漠summer2 小时前
Missing Semester 计算机教育中缺失的一课 Lecture 01 Shell
开发语言·后端·scala
jinyishu_2 小时前
C++ string使用方法
开发语言·c++
EW Frontier2 小时前
三级跳突破864维动作空间——QMIX-Hierarchical多无人机协同通信方法全解析【附python代码】
开发语言·python·无人机·强化学习·通信资源分配
名字还没想好☜2 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
乐观勇敢坚强的老彭2 小时前
C++浮点数使用注意事项
开发语言·c++