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

相关推荐
yume_sibai8 分钟前
11-Rust 不安全编程(unsafe 关键字 + 裸指针 + FFI + 内联汇编 + 内存安全保证)
汇编·安全·rust
shengjk114 分钟前
AI会让程序员失业吗?200年前的手工织工已经给出了答案
后端
盖伦发发28 分钟前
MySQL InnoDB事务完整教程|ACID、MVCC、隔离级别、事务控制
经验分享·后端·spring·软件工程
一条泥憨鱼34 分钟前
苍穹外卖【day09| 对订单的各种操作】
后端·苍穹外卖
troy1281 小时前
Python 基础语法(六):函数与模块、文件操作、异常处理
开发语言·python
前端snow1 小时前
ai agent --- AGUI 协议,流式渲染组件
人工智能·后端
用户8181870627461 小时前
第26章 Kafka vs RocketMQ vs RabbitMQ真实选型对比
java·后端
lv__pf1 小时前
09-深入理解AQS之独占锁ReentrantLock源码分析【TL 并发 09】
java·开发语言
小兔崽子去哪了1 小时前
深度学习 2 / CNN 神经网络
后端·python
这是程序猿1 小时前
Java线程池深度剖析:源码原理、核心参数、任务调度与生产调优实战
java·开发语言·python