Erlang和Go的并行化concurrent比较

原文链接:http://www.csnuts.com/msg/?id=9067

说到concurrent,一般会想到Erlang和Go语言,这两种语言的主打特性都是 concurrent,Erlang有着20多年的历史,是为简化开发电信大并发和高可靠性应用而发明的语言,Go是Google从2007年开始设 计,2009年opensource出来的,Go属于一种system language,opensource的就算这两种语言吧,公司内私有的语言则有TNSDL,SDL的一个变种,这三种concurrent语言各有不 同,下面看看:

 

 

 

1)语言设计

 

Erlang的实现基于虚拟机beam,Go是编译型语言,有着独成一体的compiler(不同于gcc,Go很好的解决了依赖的问题, 所以编译go程序时不需向编译c程序那样指定include和library),TNSDL和GO类似,属于native执行。Erlang和TNSDL 主要是为电信级应用服务的,而Go的concurrent则更具有通用性,这点主要体现在concurrent的设计,Erlang和SDL是基于 process之间传递message,而Go是goroutine组成,再加上channel,Go通过把process和message解耦使得Go 的设计更有通用性和灵活性,应用可以根据自己的需求决定是否需要channel的处理。routine加channel的设计在stackless python也有(有些人说Go = C + stackless Python),正是channel的灵活性使Go中不需要Erlang中的PID,Go中的go无返回值,Erlang中的spawn则返回PID。

 

Erlang没有对message buf进行控制,使用Go的channel则可控制channel的capacity,make(chan int, 100)

 

 

 

2)Library支持

 

Erlang有着20多年的历史,OTP中各种behavior,driver支持使得使用Erlang得心应手。Go的历史短得多,library仍有欠缺。

 

 

 

3)scheduler调度器

 

从实现的角度看Erlang中每个process都有自己的heap,所以无法共享内存,总体来说Erlang的scheduler与 Linux kernel非常相似;Go和SDL属于native执行,这里主要讨论公平性的问题,Erlang中每个process有reduction,类似于 Linux kernel中process的time slice,Go是native执行,那么Go的runtime是如何控制每个goroutine的公平性呢?答案是没有,native执行的 goroutine无法像Erlang那样保证公平性,goroutine只能在syscall、io、channel read write操作时才能有机会重新执行schedule函数,以执行其余的goroutine。在concurrent语言中,如不能很好的解决公平调度和 优先级调度是个很大的问题。

 

鉴于Go现在还不是太成熟,或许以后会有改进,scheduler和GC都有很多的讨论,现在scheduler的实现逻辑及其简单(G & M),与Erlang 调度器相比更是简单(里面有些bug,还有公平性的问题)。

 

Erlang scheduler位于:otp/erts/emulator/beam/erl_process.c

 

Go scheduler位于:go/src/pkg/runtime/proc.c

 

 

 

4)memory model 内存模型

 

Erlang中每个process有自己的heap,stack在heap的底部,这里的stack是Erlang process的stack,类似于Java中的操作数栈,stack向下增长,stack top如遇到heap top,则进行GC,GC后stack移到新的地方。

 

Go是native执行,goroutine的stack是segment stack,TNSDL的runtime也是使用这种segment stack,segment stack就是一个程序中有很多stack执行,stack的切换则通过setjmp,longjmp实现的。(setjmp和longjmp的一个主要 应用就是concurrent,另一个是在C中模拟try catch)

 

 

 

5)GC垃圾回收

 

Erlang的GC属于分代算法,有个old heap,有minor gc和full sweep,总体来说和Java类似,只不过Erlang没有mark的过程,直接根据rootset找到所有Eterm放在新分配的heap的。

 

Go现在是mark-sweep,以后会使用IBM的低延时GC算法。

 

6)高可靠性

 

Erlang中有个builtin的高可靠性,如link和monitor机制。

 Go是一个通用性的设计,虽没有built-in的link和monitor,goroutine则可使用defer来实现link的效果。

 

7)性能

 

Go的实际目标之一就是高性能,这也是为什么go是一种编译型语言。理论上分析goroutine的性能会好于Erlang的process,但软件设计原则中性能只是衡量标准之一而不是全部。

 

好了,话太多,就说到这里了,个人还是很喜欢Go的设计,未来程序语言的实际应该像go和Erlang那样扔掉 mulitthreading的设计(Java,Python),同时channel的使用使得go的实际更具通用性和灵活性,这是concurrent 语言被行业接受非常关键性的因素。

 

 

标签:Go语言Erlang


本文来自:CSDN博客

感谢作者:dean_go

查看原文:Erlang和Go的并行化concurrent比较

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。