我阅读了Joe Armstrong的"编程Erlang",以及"n核机器"理论的"n倍快".在Erlang中进行多核编程的有效方法是使用大量进程(线程).
我是一名C++程序员,所以我很好奇在C++中创建大量线程和在Erlang中创建大量进程之间的区别.我知道在C/C++中处理线程并不容易.我也知道锁定/解锁会使系统变慢.但这不是不可能,对吧?
那么..为什么Erlang是一种支持多种语言的语言?是因为它很容易编程吗?
我正在为MMORPG制作一个在线游戏服务器,这就是为什么我对Erlang作为替代服务器语言感兴趣的原因.
(我已经读过这个问题,但我认为这不是我正在寻找的问题.)
它归结为线程与进程.
操作系统是专门设计的,因此每个"用户"都认为他们自己拥有整个计算机 - 这就是为什么你以用户wwwrun运行apache的原因.
程序员作为程序员,开始超载这种范式,首先是每个运行多个"工作"的人类用户.由于操作系统是为多个用户设计的,因此该体系结构的上限扩展限制反映了登录用户的上限扩展限制- 这就是为什么apache将在4,000-8,000个用户开始死亡的原因.
流程是一个成熟的范例(我的流程不会让你崩溃).当我们开始看到线程的引入时,事情开始变得非常不同.在这里,我们有一些程序具有外部阻塞活动(等待磁盘,等待io,等待内存),希望能够一方面等待,另一方面工作,线程允许您这样做并克服两个问题:
您无法获得足够的进程,因为操作系统无法处理它
每个过程都很昂贵,因为通过设计,它为"用户"提供了操作系统的全部功能
线程的问题在于它们打破了进程设计的分离.我的线程可以丢弃你的线程 - 错误传播.
Erlang的不同之处在于许多方面.Joe Armstrong的博士论文被称为在存在软件错误的情况下制作可靠的分布式系统.
可靠性意味着流程优于线程.问题是操作系统进程太"昂贵",因为它们是为人类设计的(你拥有机器)而不是并发的程序单元.在Erlang VM中,VM具有多用户系统的全部功能(它在操作系统进程中运行),并且每个Erlang进程具有小得多的并发功率 - 如果它想要使用'大机器'它与VM进行对话,并为此做好准备.因此Erlang进程比操作进程(和线程)便宜得多.你只是产卵,产卵,产卵.开箱即用的Erlang VM以2**8个进程开始,但你可以将其提高到数百万(如果你有足够的RAM).
此外,正如Joe在博士论文第一部分的第一部分所说,要拥有可靠的软件,您需要从两台计算机开始.使用Erlang/OTP,在写入时您不知道您的软件将运行在哪台计算机上.Erlang/OTP集群在运行时将分配您的计算工作.所以Erlang进程是本机分布式的,就像spawn()(用于fork()的Erlang)和重启语义一样.
因为Erlang有自己的进程,所以它有自己的调度程序和自己的代码加载器/二进制格式(可以解释Erlang,也可以编译为本机二进制文件).这样就可以提供一小组额外的好处 - 在你编写Erlang/OTP应用程序之前,它已经可以热插拔其二进制文件等等.
因此,确保您可以使用C++编写多线程应用程序 - 但是您有责任防止错误传播并构建系统稳定性.
当然,你可以在C中构建可靠的软件 - 看看Erlang(VM是用C编写的)这就是为什么你想要的?在过去,公司编写了自己的"操作系统",您现在可以编写自己的操作系统,但为什么要这样做呢?有数百万行强大的测试代码"做到了",就像Erlang/OTP系统中有150万行强大的测试代码"做到了"一样.
使用Erlang是关于使用其他人编写的东西,只构建使您的公司有效的位.
不,这不是不可能,但Erlang确实让它变得更容易.关键是不在进程之间共享状态.Erlang凭借其作为一种功能语言实现了这一目标.该函数应该没有副作用,也不应该访问任何变量状态(除了在堆栈上传递的参数).使用这些属性,可以将系统中任何函数的计算移动到具有单独存储空间的另一个处理器,Erlang将为您执行此操作.Erlang只需要复制函数的参数和内存空间之间的结果(注意:这不适用于所有类型的应用程序......需要在非常大的输入状态下运行的函数可能会提供性能复制该状态时的问题).
在C++应用程序中初始使用线程可能会有不同的处理器(在多核系统中)尝试同时访问同一共享内存.然后,系统必须做大量工作以确保与每个核心关联的本地缓存保持一致.这是您可以遭受巨大性能命中的地方.由于这个原因,当你有多个内核时,我们的应用程序会降低性能.事实上,我甚至会说你最好设计你的应用程序只使用你需要进行异步I/O的线程,但是你需要让进程做真正的工作而不是阻塞I/O,使用完整的流程.通过使用完整进程,您可以保证每个进程都有自己的内存空间,并且没有两个线程会同时使用相同的内存(当然,然后,您需要提出一种在这些流程之间进行通信的良好方法.有了这样的系统以及管理状态和分发处理的规则,你可以获得与Erlang提供的类似的结果,但是你必须做很多Erlang已经为你做的基础设施工作.