concurrency - 函数式语言(特别是 Erlang)如何/为什么能够很好地扩展?

标签 concurrency functional-programming erlang scalability

一段时间以来,我一直在关注函数式编程语言和功能的日益增长的知名度。我调查了他们,没有看到上诉的理由。

然后,最近我参加了 Kevin Smith 的“Erlang 基础知识”演讲,地址:Codemash

我很喜欢这个演示,并了解到函数式编程的许多属性可以更轻松地避免线程/并发问题。我知道缺乏状态和可变性使得多个线程不可能更改相同的数据,但 Kevin 说(如果我理解正确的话)所有通信都是通过消息进行的,并且消息是同步处理的(再次避免了并发问题)。

但我读到,Erlang 用于高度可扩展的应用程序(这就是爱立信最初创建它的全部原因)。如果所有内容都作为同步处理的消息进行处理,那么如何才能有效地每秒处理数千个请求呢?这不是我们开始转向异步处理的原因 - 这样我们就可以利用同时运行多个操作线程并实现可扩展性?看起来这种架构虽然更安全,但在可扩展性方面却倒退了一步。我错过了什么?

我理解 Erlang 的创建者故意避免支持线程以避免并发问题,但我认为多线程对于实现可扩展性是必要的。

函数式编程语言如何才能本质上是线程安全的,同时仍可扩展?

最佳答案

函数式语言(通常)不依赖 mutating一个变量。因此,我们不必保护变量的“共享状态”,因为该值是固定的。这反过来又避免了传统语言在跨处理器或机器实现算法时必须经历的大部分跳跃。

Erlang 比传统的函数式语言更进一步,它内置了一个消息传递系统,允许一切在基于事件的系统上运行,其中一段代码只关心接收消息和发送消息,而不用担心更大的情况。

这意味着程序员(名义上)不关心消息将在另一个处理器或机器上处理:只需发送消息就足以让它继续。如果它关心响应,它将作为另一条消息等待。

最终结果是每个片段都独立于其他片段。没有共享代码,没有共享状态,所有交互都来自可以分布在(或不)多个硬件之间的消息系统。

与传统系统对比:我们必须在“ protected ”变量和代码执行周围放置互斥体和信号量。我们通过堆栈在函数调用中进行紧密绑定(bind)(等待返回发生)。所有这些都会产生瓶颈,而这些瓶颈在像 Erlang 这样的无共享系统中不是什么问题。

编辑:我还应该指出 Erlang 是异步的。您发送消息,也许/有一天会收到另一条消息。或不。

斯宾塞关于无序执行的观点也很重要并且得到了很好的回答。

关于concurrency - 函数式语言(特别是 Erlang)如何/为什么能够很好地扩展?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/474497/

相关文章:

针对写入优化的并发数据结构

lambda - 列表的最小索引 i,使得从 0 到 i 的数组元素的前缀和小于 F# 中的某个常量 c

erlang - 在 Erlang 中必须使用工作池吗?

generics - 如何在 Elixir 中类型指定泛型

二郎 : how to implement Erlang list comprehension ?

monad 中的多线程

java - 在一个线程的 JDialog 中显示一个不确定的进度条,并同时在另一个线程中运行一个任务

函数式编程: Embedding functions in AST?

Scala 性能 : imperative vs functional style

multithreading - 阅读缓存DIY书时的一个Go map线程安全问题