注册
 找回密码
 注册
江西广告网
查看: 304|回复: 0
打印 上一主题 下一主题

浅谈 C# 中的代码协同 (Coroutine) 执行支持

[复制链接]

该用户从未签到

1
跳转到指定楼层
发表于 2008-12-24 11:59:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册

x
  几个月前我曾大致分析过 C# 2.0 中 iterator block 机制的实现原理,《C# 2.0 中Iterators的改进与实现原理浅析》,文中简要介绍了 C# 2.0 是如何在不修改 CLR 的前提下由编译器,通过有限状态机来实现 iterator block 中 yield 关键字。   实际上,这一机制的最终目的是提供一个代码协同执行的支持机制。   以下内容为程序代码:      using System.Collections.Generic;      public class Tokens : IEnumerable   {   public IEnumerator GetEnumerator()   {   for(int i = 0; i   #include   #include      // The function object multiplies an element by a Factor   template   class MultValue   {   private:   Type Factor;  // The value to multiply by   public:   // Constructor initializes the value to multiply by   MultValue ( const Type& _Val : Factor ( _Val {   }      // The function call for the element to be multiplied   void operator ( ( Type& elem const   {   elem *= Factor;   }   };      int main(   {   using namespace std;      vector v1;      //...      // Using for_each to multiply each element by a Factor   for_each ( v1.begin ( , v1.end ( , MultValue ( -2 ;   }      虽然 STL 较为成功的通过迭代器、算法和谓词,将此协同执行逻辑中的行为和控制分离,谓词表现行为(MultValue、迭代器(v1.being(), v1.end())表现控制状态、算法表现控制逻辑(for_each),但仍然存在编写复杂,使用麻烦,并且语义不连冠的问题。   一个缓解的方法是将谓词的定义与控制部分合并到一起,就是类似 boost:ambda 的实现思路:   以下内容为程序代码:      for_each(v.begin(), v.end(), _1 = 1);      for_each(vp.begin(), vp.end(), cout = 0)   {   std::cout << cur << std::endl;      SwitchToFiber(fiberFor);   }      DeleteFiber(fiberFor);      上述伪代码是纤程使用的一个大概流程,可以看出实际上纤程跟上面 Ruby 和 C# 2.0 中的协同执行所需功能是非常符合的。而在实现上,纤程实际上是通过在同一线程堆栈中构造出不同的区域(ConvertThreadToFiber/CreateFiber),在 SwitchToFiber 函数中切换到指定区域,以此区域(纤程)的代码和寄存器等环境执行,有点类似于 C 代码库中 longjmp 的概念。Netscape 提供的状态线程库 State Threads library 就是通过 longjmp 等机制模拟的类似功能。   而在 .NET 1.0/1.1 中要使用纤程,则还需要考虑对每个纤程的 Managed 环境构造,以及切换调度时的状态管理等等。有兴趣的朋友可以仔细阅读上述两篇精彩文章。   以下内容为程序代码:      class CorIter : Fiber {   protected o <
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表