Rust 和Erlang的对比(4)

Erlang: Erlang中的消息传递是异步的。假设一个进程向另一个进程发送消息,如果该锁立即可用,则消息会被复制到另一个进程信箱;否则它将被复制到一个堆片段,正在接收的进程将在稍后的时间点得到它。这可以实现真正的异步和数据无竞争行为,尽管代价是在另一个进程的堆中复制相同的消息。 

Rust: Rust有通道,就像水在两点之间流动一样。如果在一条小溪上放个东西,它就会流向另一端。每当创建一个Rust通道,就会随之创建一个发射和一个接收处理器。发射处理器用于把消息放到通道上,而接收处理器阅读这些消息。一旦发射器把一个值放到了通道上,那么这个值的所有权就转移给了那个通道,如果有其他的线程从这条通道读取这个值,那么其所有权就转移给了这个线程。当使用通道时,所有权的原则仍然保留,每个值都只有一个所有者。在最后一个线程退出时,资源被垃圾回收。

共享的突变

Erlang: 在Erlang中共享是一种罪,但是Erlang允许使用Erlang Term Storage(ETS)进行控制突变。ETS表可以跨多个表共享,并在内部同步,以防止竞争。ETS可以调优,以带来高的读并发性或高的写并发性。整个表可以附加到一组进程中,如果所有这些进程退出,整个表将被垃圾回收。 

Rust: 作为一种低级语言,Rust提供了一种资源共享突变的方式。结合引用计数与互斥量,资源访问与多个线程的突变同步。如果共享相同资源的多个线程退出,资源将被最后一个退出线程垃圾回收。这提供了一种干净、高效的共享、变异和清理资源的方式。

行为

Erlang: 是共同模式的形式化。其思想是将一个过程的代码划分为一个通用的部分(行为模块)和一个特定的部分(一个回调模块)。您只需要实现一些回调,并调用特定的API来使用行为。有各种标准的行为,如genserver、genfsm、gensupervisor等。例如,如果您想要一个独立的进程,可以像服务器一样持续运行,侦听异步和同步调用或消息,那么您就可以实现它的genserver行为。它还可以实现自定义行为

Rust: 如果你有一组在多种数据类型中通用的方法,它们可以被声明为一个特征(trait)。特征是Rust版的接口,它们是可扩展的。Traits消除了对传统方法重载的需求,并提供了一种操作符重载的简单模式。 

内存分配

Erlang: 变量在Erlang中是动态强类型的。在运行时不提供类型定义,并且在运行时最小化类型转换以防止类型错误。当程序运行时,变量会在底层OS线程的堆上动态分配,并在垃圾回收时释放。 

Rust: Rust是一种静态的,严格的和推断的语言。静态意味着Rust编译器会在编译期间检查类型以防止运行时发生类型错误。有些类型是在编译过程中推断出来的,比如:最初声明为String类型的字符串变量被分配给不同的变量,不需要隐式地声明类型,新变量的数据类型将由编译器本身推断出来。编译器努力确定哪些变量可以分配到堆栈上,哪些变量可以分配到堆上,因此Rust内存分配非常高效和快速。与Erlang不同的是,在很大程度上,Rust使用堆栈分配所有在编译时已知大小的数据类型,而动态数据类型(如Strings,Vectors等)则在运行时在堆上分配。

可扩展性、容错性、分布式

Erlang BEAM是Erlang的一个独特特性。BEAM的构建方式是可扩展性、容错性、分布性、并发性等的基础保证。

Erlang如何扩展?与操作系统中的本地线程不同,BEAM可以支持称为绿色线程的轻量级进程,这些进程通常是使用很少的本地操作系统线程分离出来的。从字面上看,可以从任何一个本地操作系统线程中分离出一百万或更多的Erlang进程。通过将大堆块分配给本地线程并在多个Erlang进程间共享,使这一点成为了可能。每个Erlang进程都会获得一块来存储它的所有变量。由于它的大小可能只有233个字,本地操作系统线程的堆完全可以应对一百万个进程。此外,由于Erlang内置的异步消息传递,进程之间的通信几乎不是瓶颈。一个进程永远不会被阻塞,以便向其他进程发送消息:它或者试图获取对另一个进程信箱的锁定,直接将消息放入其中,或者将消息放入单独的堆片段中,并将该堆片段附加到其他进程堆。Erlang虚拟机还具有内置的分布功能,可以运行进程并以透明的方式跨机器与它们进行交互。 

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/97c0db980c0ffb0e8e85ab46f9cbb20f.html