在.NET应用程序中进行Erlang风格的并行编程(第1部分)——CCR

来源:互联网 发布:2017网络诈骗案件 编辑:程序博客网 时间:2024/04/29 22:03

在.NET应用程序中进行Erlang风格的并行编程(第1部分)——CCR

作者 Jonathan Allen译者 赵劼

【整理】:Ackarlix

发布于 2008年12月22日 上午6时37分

 

Erlang能够用来编写高度可伸缩的并行应用程序,其中经常会出现数以百万计的轻量级组件,这种类似于线程的组件被称之为actor。不幸的是,这往往需要您使用Erlang这种相对神秘的编程语言重写所有代码。不过我们也有其他选择,例如使用名不见经传的CCR平台来进行开发,该平台由.NET机器人部门开发。

作为一种基于Actor的语言,Erlang通过Actor模型能够实现高度并发性。在这个模型中,最基础的并行单元不是线程或纤程(fiber) ,而是一种更为轻量级的东西。作为Erlang中的“进程”,每个并行单元在一个32位系统中只占用大约1200字节的基础资源。与此相对的是,Windows操作系统中的每个线程默认会在栈上分配1MB空间,此外还需要额外的空间来作为簿记(Bookkeeping)和线程本地存储。由于非常轻量,一个应用程序轻松支持百万计的进程进行并发处理。

在任一时刻,大部分的进程处于空闲状态。当一个进程接受到了一条消息,运行平台将为其分配一个线程来应答这条消息。一条应答可能会创建一个新的进程,向其他进程发送消息,或者改变自身状态。一旦消息被处理之后,这个进程将会死亡,或者继续等待下一条消息。

消息处理系统实现了高端的并行性和高性能。每条消息都为异步发送,使得进程之间相互高度独立。平台能够通过消息来得知应该唤醒哪个进程。由于每个进程都能被任意的线程来处理,因此就可以大大减少耗费相对昂贵的上下文切换操作。

.NET中使用CCR,也就是Coordination Currency Runtime作为Erlang模型的回应。CCR原本面向机器人平台,正在设法扩展更广阔的市场。Siemens Automation的一个开发人员只花了几年时间就将CCR集成进他们目前的Blackboard代码库。Blackboard是一个使用AI代理和传送带将信件以10米每秒的速度进行分发的系统,包含数百万行遗留代码。Tyco是个负责从小商店到白宫的各种事情的安全公司,也在数周内与CCR进行了集成。这些并非是推销性质的案例,Siemens和Tyco没有借助微软的帮助就完成了大量的工作。

CCR的核心是一个名为“端口(port)”的API级别的概念。有别于以往调用类方法的方式,开发人员使用向端口发送消息来执行操作。附加在端口上的调控器会读取消息,如果它们符合特定的标准,就会将消息成批地交给任务进行处理。任务会被放进分发队列中,稍后就会被线程池执行。

调控器形成了调度单元的基础。它们可以只是个简单地单个端口的接收器,或多个端口的联合/选择接收器。如果需要更复杂的逻辑,它们甚至可以进行各种组合。不过它们的最终目的只有一个,那就是在收到数据时唤醒并执行一系列代码。

CCR的真正威力来自C#的迭代器语法“yield return”。Yield return是一种延续的方式,它不会挂起一个真正的线程,而实现暂停线程执行并在以后唤醒的效果。这个特性一般用于迭代,不过结合了CCR就能扩展为任意类型的异步操作。这样做的最大好处是不需要大规模修改您的现有代码。

2008 PDC中的这段示例代码展示了如何使用端口来发起一个异步调用。与阻塞方式,或者在异步调用模式中使用显式回调函数的方式不同,我们只要简单的通过yield return语句来跳出函数即可。当获得数据,同时有空余线程时,函数就会“毫不知情”地从下一行代码开始继续执行。

fs.BeginRead(buffer, 0, buffer.Length, arPort.Post, null);

// yield until stream posts IAsyncResult on the CCR port

yield return arPort.Receive();

// extract result, it must be in the port

var ar = (IAsyncResult)arPort.Test();

int read = fs.EndRead(ar);

CCR有望被包含在.NET 4.0/Visual Studio 2010中。

查看英文原文:Erlang Style Concurrency for .NET Applications Part 1 - CCR