作者:万花_筒乙姬睦美 | 来源:互联网 | 2023-06-06 13:45
最近抽时间看了些Erlang的东西,蛮有趣,纯正的函数式编程,进程消息的编程模型。当然,我最关心的的还是隐藏在语言设计背后关于构建健壮的系统基本哲学。函数式编程这个东东已经算
最近抽时间看了些Erlang的东西,蛮有趣,纯正的函数式编程,进程/消息的编程模型。当然,我最关心的的还是隐藏在语言设计背后关于构建健壮的系统基本哲学。
函数式编程这个东东已经算不上新鲜了,本来也不新鲜,Lisp里面早就有了。Erlang看上去是很纯正的FP语言,looks good!不过我个人对FP一直有点担心的就是这个东西离机器模型实在是太远,很多操作看上去倒是很美很直观外加简洁,比如用三两行代码就可以搞定快速排序,不过它底下到底是如何实现的就不清楚了,效率如何也不知道。尽管是开源的,老是去看源代码也不现实吧。理解它代码模式匹配的时候倒是让我想起了C++里面的template,模板元编程这鬼东西不就是这样一个匹配再匹配的过程吗。当然,如果FP实现的东东成为效率瓶颈的时候,一可以换算法(这里指的实际是换写法,比如快牌的算法不变,但是可以采用不同的表达),二可以用其它语言比如C实现后混合语言调用,现在不是提倡混合语言开发嘛。如果考虑到80/20法则,其实更重要的还是需要大家转变思维。
其实以前也看过些介绍Erlang的小文章,听说它可以随意创建进程,当时就是一惊,要知道OS里面创建、管理和销毁进程可都是些绝对重量级的操作啊。深入了解后才发现Erlang里面的进程并不是操作系统里面的进程。学过操作系统原理的人都知道,任何程序实际上都是在一个线程(Thread)里面运行,或者说任何一段code执行的时候总是对应着一个ThreadInfo,里面记录了code当前运行的一陀信息。而进程只是一堆资源的集合,换个说法就是进程里面的这些资源只能在进程内部访问,跨进程访问一般都是非法的,Windows下应用程序偶尔会出现的非法地址访问,其实就是试图访问不属于自己进程的资源被操作系统reject了:) Erlang里面的进程实际上就是在Erlang虚拟机上面的资源集合,因为这个进程只是属于Erlang专用的,它只需要对Erlang虚拟机负责,所以直觉上可以想象它只需要支持有限的操作,也不需要考虑什么兼容性等烦人的问题,所以就是一个最原始也最标准概念上的进程。现在回过头来想想也是,就是表示一个资源的集合,本就应该和OO里面的一个Object没什么区别。一个Object表示的是数据和相关的操作,进程表示的是资源的集合。我们在任何一种OO语言里面编程的时候99.99999...%的时间是不用担心创建对象的数量的,当然我们在Erlang里面创建进程的时候也不应该有什么担心。
Erlang的目标是用以构建安全、稳定大规模系统,但是任何有理智的人都知道,大型系统是决不可能bug free的(简单的程序有没可能?我不知道)。即便除开硬件等其它因素,但就软件本身而言,无论语言怎么设计,developer如何高超,测试如何系统,anyway,传说中的臭虫总会在夜深人尽的时候跳出来捣乱。Joe爷爷在Erlang里给出的解决办法本质上还是降低模块间的耦合度,既然错误不能避免,那就应该尽可能地让错误限制在更小的范围内,而且最好是能够从错误中恢复过来。进程的概念本身就是用来管理资源访问的,Joe爷爷把它用到Erlang里面自然是理所当然。像我等凡夫俗子,一直都天真地认为进程是属于操作系统的,差距啊!
至于消息就没什么可说的了,既然一切都是进程,而内存又无法在进程间共享,消息机制当然就是进程间合作的最佳选择了。
另外值得一提的是“进程+消息”这种模型最近可是没少露脸。除了Erlang,微软研究院(MSR)开发的singularity原型操作系统,IE8,Google chrome,包括周鸿祎的360浏览器据说都使用了类似的思想。而且像COM,.NET中的AppDomain等也都可以说是神似。另一门语言Python采用的是OS原生的线程+锁机制,不过据说Guido也有意在未来采用多虚拟机+IPC通信的方式来增强Py的scalability,看来这种模型已经是被大家公认的解决方案了。
关于构建大型系统的基本思想,Joe的博士论文《面对软件错误构建可靠的分布式系统》讲的深入浅出(链接里面中、英文版的都有),推荐大家有空读下,相信一定和我一样受益匪浅 (题外话:不知道Joe的这种没有一个公式的论文在国内能否通过评审,呵呵...)