[摘要]几个月前我曾大致分析过 C# 2.0 中 iterator block 机制的实现原理,《C# 2.0 中Iterators的改进与实现原理浅析》,文中简要介绍了 C# 2.0 是如何在不修改 CL...
几个月前我曾大致分析过 C# 2.0 中 iterator block 机制的实现原理,《C# 2.0 中Iterators的改进与实现原理浅析》,文中简要介绍了 C# 2.0 是如何在不修改 CLR 的前提下由编译器,通过有限状态机来实现 iterator block 中 yield 关键字。
实际上,这一机制的最终目的是提供一个代码协同执行的支持机制。
以下内容为程序代码:
using System.Collections.Generic;
public class Tokens : IEnumerable<string>
{
public IEnumerator<string> GetEnumerator()
{
for(int i = 0; i<elements.Length; i++)
yield elements[i];
}
...
}
foreach (string item in new Tokens())
{
Console.WriteLine(item);
}
在这段代码执行过程中,foreach 的循环体和 GetEnumerator 函数体实际上是在同一个线程中交替执行的。这是一种介于线程和顺序执行之间的协同执行模式,之所以称之为协同(Coroutine),是因为同时执行的多个代码块之间的调度是由逻辑隐式协同完成的。顺序执行无所谓并行性,而线程往往是由系统调度程序强制性抢先切换,相对来说Win3.x 中的独占式多任务倒是与协同模型比较类似。
就协同执行而言,从功能上可以分为行为、控制两部分,控制又可进一步细分为控制逻辑和控制状态。行为对应着如何处理目标对象,如上述代码中:行为就是将目标对象打印到控制台;控制则是如何遍历这个 elements 数组,可进一步细分为控制逻辑(顺序遍历)和控制状态(当前遍历到哪个元素)。下面将按照这个逻辑介绍不同语言中如何实现和模拟这些逻辑。
Spark Gray 在其 blog 上有一个系列文章介绍了协同执行的一些概念。
Iterators in Ruby (Part - 1)
Warming up to using Iterators (Part 2)
文章第 1, 2 部分以 Ruby 语言(语法类似 Python)介绍了 Iterator 机制是如何简化遍历操作的代码。实际上中心思想就是将行为与控制分离,由语言层面的支持来降低控制代码的薄记工作。
以下内容为程序代码:
def textfiles(dir)
Dir.chdir(dir)
Dir["*"].each do (北联网教程,专业提供视频软件下载)
……