|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?注册
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 < |
|