0 language-agnostic compiler-construction asynchronous async-await
我试图理解编译器/解释器/内核为你做的所有低级东西(因为我是另一个认为他们可以设计出比大多数其他语言更好的语言的人)
引发我好奇的众多事物之一是 Async-Await。我检查了几种语言的底层实现,包括 C#(编译器从糖代码生成状态机)和 Rust(状态机必须从 Future trait 手动实现),它们都使用状态机实现 Async-Await。通过谷歌搜索(“异步复制堆栈框架”和变体)或“类似问题”部分,我没有发现任何有用的东西。
对我来说,这种方法似乎相当复杂且开销很大;
你不能通过简单地将异步调用的堆栈帧内存复制到/从堆来实现 Async-Await 吗?
我知道某些语言在架构上是不可能的(我感谢 CLR 做不到,所以 C# 也做不到)。
我是否错过了使这在逻辑上不可能的东西?我希望通过这种方式实现更简单的代码和性能提升,我错了吗?我想当你在异步调用(例如递归异步函数)之后有一个很深的堆栈层次结构时,你需要 memcopy 的数据量相当大,但可能有办法解决这个问题。
如果这是可能的,那么为什么不在任何地方完成?
是的,将代码转换为状态机的另一种方法是复制堆栈。这是 Go 语言现在的做法,也是 Java 将在Loom 项目发布时这样做的方式。
对于现实世界的语言来说,这不是一件容易的事情。
例如,它不适用于 C 和 C++,因为这些语言允许您指向堆栈上的内容。这些指针可以被其他线程使用,因此您无法将堆栈移开,即使可以,您也必须将其复制回完全相同的位置。
出于同样的原因,当您的程序调用操作系统或本机代码并在同一线程中被回调时,它不起作用,因为有一部分堆栈是您无法控制的。在 Java 中,只要堆栈上有本机代码,Loom 项目的“虚拟线程”就不会释放线程。
即使在您可以移动堆栈的情况下,它也需要运行时环境中的专门支持。堆栈不能只是复制到字节数组中。它必须以允许垃圾收集器识别其中的所有指针的表示形式复制。例如,如果 C# 要采用这种技术,它将需要对公共语言运行时进行大量扩展,而实现状态机可以完全在 C# 编译器中完成。
归档时间: |
|
查看次数: |
170 次 |
最近记录: |