热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

What’sallthisfussaboutErlang

转载:http:blog.sina.com.cnsblog_49faf32901008pap.html作者:JoeArmstrong原文:

转载:http://blog.sina.com.cn/s/blog_49faf32901008pap.html

 

作者:Joe Armstrong
原文:What’s all this fuss about Erlang
译者:朱照远(Joshua Zhu) 许式伟(XuShiWei)


What’s all this fuss about Erlang?

没人可以预言未来,但我却打算做一些有依据的推测。

让我们假设 Intel 是正确的,而且 Keifer 项目会获得成功。如果是这样,那么 32 核的处理器在 2009/2010 年就将会出现在市场上。这毫不奇怪,Sun 已经制造出了 Niagara,它拥有 8 个核,每个核运行 4 个超线程(这相当于 32 个核)。这是一个令 Erlang 程序员欢呼雀跃的进展。为此,他们已经等待了 20 年,现在,是获得回报的时候了。

对于 Erlang 程序员来说,好消息是:你的 Erlang 程序在 N 核的处理器上运行将快 N 倍。

这是真的吗?

差不多吧。尽管为时尚早,但我们仍很乐观(相当地乐观,在过去的 20 年里,我从来没见过如此的乐观!)。

有时我们需要对我们的程序作点小调整 ―― 当我在一台 Sun Niagara 机器(拥有相当于 32 个核)上生成 Erlang 文档时,我把我的程序改了一行(我把一个 map 换成了 pmap ―― 不好意思,我在这里提一点技术细节,pmap 只是“并行的map” (parallel map) 而已)。这个程序(它根据 wiki 标记生成 63 篇文档)的运行速度提高了 7 倍。不是 32 倍,这一点我承认,但是已经显著的加快了。(后来的工作使我们意识到我们是在写盘时遇到了 I/O 瓶颈,所以除非能够让磁盘的 I/O 也并行了,否则我们会停留在这个 7 倍上 :-)

在 Ericsson,这个我工作和 Erlang 被开发出来的地方,我们正在把一些应用程序移植到 4 核处理器上 ―― 你猜怎么着?在作了一些小调整后,它们运行几乎都快了 4 倍。呵呵,对 Intel 在实验中的 80 个核的处理器,我们有点等不及了……

为什么我们的程序运行得更快了?这全跟可变状态(mutable state)和并发(concurrency)有关。

可变状态和并发

回首过去(20 多年以前),有两种并发模型:

  • 共享状态并发(Shared state concurrency)
  • 消息传递并发(Message passing concurrency)

现在,整个世界都走了一条路线(朝着共享状态的方向),而我们选择了另一条。几乎没有其他语言沿“消息传递并发之路”而行,例外的则有 Oz 和 Occam。在消息传递并发模型中,我们宣称其中没有共享状态。所有的计算都在进程中完成,并且交换数据的唯一途径是通过异步消息传递。

那为什么这是有益的呢?

共享状态并发模型被“可变状态”(顾名思义就是可被修改的内存)的思想所拖累。所有像C,Java, C++等等的语言,都认为有一种东西叫“内存”,我们可以去修改它。只要你仅有一个进程对内存进行修改,那它就没什么问题。但是如果你有多个进程共享并且修改同一内存的话,则后患无穷――这是很愚蠢的。

为了防止对共享内存的同时修改,我们需要一种锁机制。你称它为互斥体(mutex)也好,同步方法(synchronised method)也好,或者其他你愿意的名字,它仍然是锁。如果程序在临界区(即当它们持有锁的时候)崩溃,灾难就来了。所有其他的程序都将不知所措。

程序员怎么修正这些问题呢?他们不修正。他们只有祈祷。在单核处理器上,他们的程序或许还可以工作,但是在多核上――灾难。有各种各样解决这个问题的方案(事务型内存(transaction memories)可能是最好的)。但是,在最好的情况下,它们也仅仅是“杂烩”,最坏情况下,它们就是噩梦。

Erlang 没有可变的数据结构
(虽然不是百分百的准确,但也足够准确了)

没有可变的数据结构 = 没有锁
没有可变的数据结构 = 容易并行化

我们如何做并行呢?很简单,程序员将问题的解决方案分解成许多并行的进程。

这种编程风格有它自己的术语――它叫面向并发编程(Concurrency Oriented Programming Concurrency Programming)Erlang 并不是面向对象的 ――它有它自己的表示方法。

对象下台,并发上场。

世界是并发、并行的,同一时刻发生着很多事情。如果我没有很直觉地理解并发的思想,那么我不可能在公路上开车。我们一直在进行着纯粹的消息传递并发。想象有一群人,他们没有共享的状态。我有我的私有的记忆(在我的脑海里面),你有你的,二者并不共有。我们通过传递信息的方式(声波和光波)进行交流。基于这些信息的接收,我们更新我们的私有状态。

简而言之,这就是面向并发编程。

就把可变状态隐藏在对象里面(译者按:这是面向对象的核心理念之一――封装变化)而言:正是这个特性使得并行成为一个几乎不可能解决的难题。

它有效吗?

是的。 Erlang 在那些对可靠性很看重的高科技项目中被广泛使用着。 Erlang 的旗舰项目(由瑞典的电信公司 Ericsson 创立)是 AXD301 ,它有超过 2 百万行的 Erlang 代码。AXD301 已经获得了九个 9 的可靠性(是的,你读的没错, 99.9999999% )。让我们把它放到这样的背景:五个 9 已经被认为是优秀了(宕机时间 5.2 分钟/ 年),七个 9 几乎就达不到……,但是我们做到了九个 9 。

为什么呢?因为没有共享状态,加上还有一个精妙的错误恢复模型。你可以在我的博士论文中了解全部的细节。

谁在使用 Erlang?

  • “了解内幕”的人们
  • 初创企业
  • Ericsson
  • wings, 一个 3D 建模程序 http://www.wings3d.com/
  • ejabberd, 一个即时消息服务器(jabber/XMPP)
  • tsung, 一个多协议分布的负载测试工具
  • yaws,一个性能非常高的 web 服务器
  • 数以千计的(“我希望我可以在上班时间做这个”)的爱好者

Erlang 难吗?

不――不过它有点与众不同。Erlang 没有“一种类似于 C 的语法以使之容易被学习”,它既不是“面向对象的”,也没有“可变状态”,它是一门“函数式编程语言(Functional Programming Language)”。

这就是所有让人感到害怕――并让新的使用者望而却步的东西。然而有意思的是,Erlang 其实是一门非常小而且简单的语言。可能你正在对 Erlang 代码看上去的样子感到迷惑不解。 Erlang 大量使用了模式匹配语法;这里有一个 Erlang 代码的小例子(摘自新版的 Programming Erlang 一书):

-module(geometry).
-
export([area/1]).
area({rectangle, Width, Ht}) -> Width * Ht;
area({square, X}) -> X * X;
area({circle, R}) -> 3.14159 * R * R.

现在,让我们在 Erlang shell 中编译并运行它:

1> c(geometry).
{ok,geometry}
2> geometry:area({rectangle, 10, 5}).
50
3> geometry:area({circle, 1.4}).
6.15752

相当的简单……以下是做类似事情的 Java 代码:

abstract class Shape {
  
abstract double area();
}
class Circle extends Shape {
  
final double radius;
  
Circle(double radius) { this.radius = radius; }
  
double area() { return Math.PI * radius*radius; }
}
class Rectangle extends Shape {
  
final double ht;
  
final double width;
  
Rectangle(double width, double height) {
    
this.ht = height;
    
this.width = width;
  
}
  
double area() { return width * ht; }
}
class Square extends Shape {
  
final double side;
  
Square(double side) {
    
this.side = side;
  
}
  
double area() { return side * side; }
}

我从哪里下载 Erlang ?

你可以从 erlang.org 下载 Erlang。

我如何进一步了解 Erlang ?

哦,我刚写完了 Programming Erlang: Software for a Concurrent World (Pragmatic Bookshelf, US$36.95, 978-1-934356-00-5) 一书。这是一本 Erlang 的教程导引。它覆盖了整个语言,并且包含了许多演示程序及其完整的源代码,其中包括:

  • 一个类似 irc/chat 的系统
  • 一个流媒体 SHOUTcast 服务器
  • 一个用来构建全文检索系统的 map-reduce 实现

博客

在博客圈子里面气氛非常活跃,你可以访问 Google 搜索引擎搜索 Erlang 博客。此外,这里还有一些你可能喜欢的文章:

  • More Erlang
  • Concurrency is Easy
  • Web 2.0 is Shifting

网络文档
现在去看看这个目录吧。你将在这里找到 50 多个 PDF 文件。我已经为你挑选了其中的一些,以供你查阅:

  • getting_started-5.5.3.pdf
  • tutorial-5.5.3.pdf
  • programming_examples-5.5.3.pdf
  • design_principles-5.5.3.pdf
  • efficiency_guide-5.5.3.pdf
  • asn1-1.4.4.12.pdf
  • dialyzer-1.5.1.pdf
  • inets-4.7.8.pdf
  • mnesia-4.3.3.pdf
  • parsetools-1.4.1.pdf
  • reference_manual-5.5.3.pdf
  • sasl-2.1.4.pdf
  • snmp-4.8.4.pdf

它们中的每一个都代表了一本有待编纂的书 :-)

祝你阅读愉快!

版权所有 (C) 2007 Joe Armstrong


推荐阅读
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 嵌入式处理器的架构与内核发展历程
    本文主要介绍了嵌入式处理器的架构与内核发展历程,包括不同架构的指令集的变化,以及内核的流水线和结构。通过对ARM架构的分析,可以更好地理解嵌入式处理器的架构与内核的关系。 ... [详细]
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了软件测试知识点之数据库压力测试方法小结相关的知识,希望对你有一定的参考价值。 ... [详细]
  • MySQL数据库锁机制及其应用(数据库锁的概念)
    本文介绍了MySQL数据库锁机制及其应用。数据库锁是计算机协调多个进程或线程并发访问某一资源的机制,在数据库中,数据是一种供许多用户共享的资源,如何保证数据并发访问的一致性和有效性是数据库必须解决的问题。MySQL的锁机制相对简单,不同的存储引擎支持不同的锁机制,主要包括表级锁、行级锁和页面锁。本文详细介绍了MySQL表级锁的锁模式和特点,以及行级锁和页面锁的特点和应用场景。同时还讨论了锁冲突对数据库并发访问性能的影响。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 成功安装Sabayon Linux在thinkpad X60上的经验分享
    本文分享了作者在国庆期间在thinkpad X60上成功安装Sabayon Linux的经验。通过修改CHOST和执行emerge命令,作者顺利完成了安装过程。Sabayon Linux是一个基于Gentoo Linux的发行版,可以将电脑快速转变为一个功能强大的系统。除了作为一个live DVD使用外,Sabayon Linux还可以被安装在硬盘上,方便用户使用。 ... [详细]
author-avatar
空心悟心
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有