真实世界的并发

我们来先把编程忘掉一会儿,想想现实世界中会发生的事情。

车流

我们 了解并发

我们的大脑对并发,有着深刻理解。运用大脑中称为 杏仁核,amygdala 的部分,我们对刺激反应极快。要是没有这种反应,我们就会死掉。有意识的思考速度太慢;在 “踩刹车” 这个想法本身形成时,我们就已踩下了刹车。

在主干道上开车时,我们会在脑海中追踪几十辆,甚至上百辆车的位置。这是在无意识的思考下完成的。如果咱们做不到这点,我们可能早就死了。

世界是并行的

当我们打算编写行事方式与现实世界中其他物体行事方式相同的程序时,那么这些程序将有着并发的结构。

这就是我们应该以并发编程语言编程的原因。

然而,我们通常会以顺序编程语言,编程一些现实世界应用。这属于不必要苦头。

使用一门设计用于编写并发应用程序的语言,并发开发就会变得容易得多。

Erlang 程序建模了我们思考与交互的方式

我们没有共用的存储。我有我的记忆。你有你的记忆。我们俩有两个大脑,一人一个。他们没有连接在一起。要改变你的记忆,我就要发送给你一条消息:我说话,或者挥动我的手臂。

你听到,你看到,于是你的记忆改变了;但是,在没有问你一个问题,或观察你的反应下,我就不直到你已收到我的消息。

Erlang 进程就是这样的。Erlang 进程间没有共用的内存。每个进程都有其自己的内存。要更改某个别的进程内存,咱们必须向其发送一条消息,并希望他能接收并理解该消息。

要确认另一进程已收到了咱们的消息并更改了其内存,咱们就必须询问他(通过发送给他一条消息)。这正是我们交互的方式。

Sue: Hi, Bill, my telephone number is 345-678-1234.

Sue: Did you hear me?

Bill: Sure, your number is 345-678-1234.

这些互动模式,是我们众所周知的。从出生开始,我们就学了通过观察外界、向外界发送信息并观察其反应,与外界互动。

人充当了作为经由发送消息沟通的独立实体

这是 Erlang 进程的工作方式,也是我们的工作方式,所以理解 Erlang 程序很容易。

Erlang 程序由数十个、几千个甚至数十万个小的进程组成。全部这些进程都独立运行。他们通过发送消息相互通信。每个进程都有私有存储。他们像一屋子在互相唠叨的人那样行事。

这使得 Erlang 程序本质上易于管理和扩展。设想我们有十个人(进程),并且他们有太多的工作要做。怎么办?增加人手。怎样管理这些人群呢?很简单 -- 只要向他们喊出指令(广播)。

Erlang 进程不共用内存,因此在使用中内存无需加锁。有锁的地方,就有可能丢失的钥匙。咱们丢了咱们的钥匙会发生什么?咱们会惊慌失措,不知所措。这就是咱们丢失了钥匙及锁出错时,那些软件系统中的情况。

带有锁和钥匙的分布式软件系统,总是会出错。

Erlang 没有锁,也没有钥匙。

当某人死了,其他人将注意到

当我在某个房间里,突然倒地死去,有人将可能注意到(至少我希望如此)。Erlang 的进程就像人一样 -- 偶尔也会死掉。与人不同的是,当他们死掉时,他们会用他们最后一口气,喊出到底死于什么原因。

想象一个坐满了人的房间。突然有一个人倒地死去。就在他们死的时候,他们会说 “我死于心脏病发作” 或者 “我死于胃部爆炸”。Erlang 进程就是这么做的。某个进程死的时候可能会说 “我要死了,因为我被要求除以零”。另一进程可能会说:“我要死了,因为我被问到一个空列表中的最后元素是什么。”

现在在这个满是人的房间里,我们可以设想有专门指派负责清理尸体的人。我们来设想两个人,Jane 和 John。当 Jane 死掉时,随后 John 将将解决与 Jane 死亡有关的任何问题。当 John 死掉时,那么 Jane 将解决这些问题。Jane 和 John 通过一份规定了当其中一人死亡时,另一人将解决因该死亡而造成的任何问题的无形协议,联系在一起。

这便是 Erlang 中错误检测的工作原理。两个进程可被链接。当其中一个进程死亡,另一进程就会收到一条说明第一个进程死亡原因的消息。

基本上就是这样。

这就是 Erlang 程序的工作原理。

以下是我们目前所学到的:

  • Erlang 程序由许多进程组成。这些进程可以相互发送消息;
  • 这些消息可能会被收到并理解,也可能不会。当咱们想要知道,某条消息是否被接收并理解时,咱们必须发送给该进程一条消息并等待回复;
  • 成对进程可以被链接起来。当链接进程对中的某个进程死亡时,该进程对中的另一进程将收到一条包含着第一进程死亡原因的消息。

这种简单的编程模型,是我(作者)称为 面向并发编程模型 的一部分。

下一章中,我们将开始编写并发程序。我们需要学习三个新的原语:

  • spawn
  • send(使用 ! 运算符)
  • receive

然后我们就可以编写一些简单的并发程序。

当进程死掉时,某个别的与之连接的进程,就会注意到。这是 第 13 章 “并发程序中的错误” 的主题。

当咱们阅读接下来的两章时,请设想房间里的人们。这些人就是一些进程。房间里的人,都有单独的私有记忆;这便是某个进程的状态。为改变咱们的记忆,我要跟你讲话,而你则会听我讲。这就是发送和接收信息。我们有孩子;这就是下蛋。我们死亡;这是就进程退出。

知识点

  • concurrency-oriented programming
Last change: 2025-09-15, commit: 650d930

小额打赏,赞助 xfoss.com 长存......

微信 | 支付宝

若这里内容有帮助到你,请选择上述方式向 xfoss.com 捐赠。