虽然 Mono 在大多数情况下都紧跟 C#和 Common Language Infrastructure 规范,但有时候它也会超越他们。虽然诸如 SIMD 支持等特性是向后兼容于.NET 的,但运行时支持的 continuations 却是 Mono 所独有的。
continuation 类似于冻结的线程,如果你愿意还可以称其为快照。它包含了栈帧和局部变量,但与真正的线程不同的是它无法执行。C#的 yield 操作符就是 continuation 的一种简化形式,但 yield 只不过是编译器所玩的一个小把戏,它会创建一个状态机而并非通用的 continuation。因此大多数情况下你需要运行时的支持才行。
Tomi Valkeinen 对运行时支持的研究成果就是 Mono.Tasklet API 。它考虑到了通用的 continuations,可以捕获到栈,同时又可以在必要的情况下恢复。值得注意的是,这种形式的 continuation 可以捕获到引用,但却无法捕获到这些引用所指向的堆中的对象。Tomi Valkeinen 在 Mono.Tasklet API 的基础上构建了 microthreading 库。它包含了轻量级的线程,可以通过 continuations 和多任务共享单独的一个物理线程。
方才我们说“大多数情况下”,这是因为还有另一种构建通用 continuation 的方式。来自 LindenLabs 的 Jim Purbrick 构建了一个 continuation 系统,使用CIL 进行了重写而非运行时支持。相对于Valkeinen 的continuation 来说,这是一种重量级的构建continuation 的方式。但它不仅可以序列化栈,还可以序列化堆中的对象。这样就可以在另一台服务器上恢复continuation 了,这对于Second Life 的可伸缩架构是至关重要的。从长远来看,LindenLabs 想要将这两种技术整合起来:使用Mono Tasklets 实现快速的continuations,使用自己的技术实现需要序列化的continuations。
评论