# Erlang 的世界观
Erlang 的核心其实就是6个函数,真正搞懂它们,你就明白 Erlang 的世界观了。
spawn, send, receive, register, whereis 和 self。就这6个函数,组成 Erlang 的世界观。
让我们来了解 Erlang
Erlang 的世界中充满了进程,很多很多进程。我们暂时不用计算机术语,而是看看身边的世界。我们的世界充满了人,很多很多人。每个人都有一个大脑,里面包含了仅属于我们自己的记忆。我不知道你脑子里面在想什么,你不知道我脑子里在想什么,除非我问你,”约吗?“。你说:”约“。我们两个的记忆分别产生了些许变化。
从我们出生到现在,我们一直在维护大脑中的这份记忆,随着与外界的不断交互我们不停地在更新着这份记忆。我们学到很多与人打交道的方式,我们说话、写信、发短信、打电话。我们给别人留个字条,然后干自己的事去了;或者给人发个微信,然后接着上网吃瓜。这就是异步消息传递。
Erlang 的世界和我们的真实世界很像。每个 Erlang 进程维护着自己独有的内存,别的进程无法访问其内部状态,除非它们互发消息进行交流。所有的消息传递都是异步的,就像我们的现实世界
听起来很简单吧!代码写出来啥样?
1>spawn(foo,hello,[]).
<0.70.0>
这样就会创建一个新的进程,调用foo:hello()。进程一旦执行完这个函数就会死掉,将所有分配到的内存还给BEAM。
如果你想创建两个进程同时做事,只需spawn两次:
1>spawn(foo,hello,[]).
<0.70.0>
2>spawn(foo,hello,[]).
<0.71.0>
这将创建两个进程并发调用foo:hello()。这就是 Erlang 的并发模型——也叫参与者模式 (Actor model)。
如果你想整100个进程同时做事,调用spawn 100次即可。简单粗暴。
现在我们知道如何创建进程,接下来是给它发消息。
1>Pid=spawn(foo,loop,[]).
<0.80.0>
2>Pid!hello.
hello
这里我们启动一个进程调用 foo:loop()。我们假设这个loop函数会递归调用自己,这样我们的进程不会一下就死掉。spawn 会返回一个进程ID <0.80.0>,我们将其绑定到 Pid 变量中,并向其发个消息 hello。 Erlang 里用惊叹号 ! 发消息。好了,以上就是异步消息发送。这也是 Erlang 中两个进程之间交流的唯一手段。
当消息被发给某进程后,该进程如何收消息呢?
1>Pid=spawn(fun()->
1>receive
1>hello->io:format("Got hello message~n")
1>end
1>end).<0.86.0>
2>Pid!hello.
Got hello message
hello
用 receive 来收消息。你可以在这里用模式匹配来匹配你想要接收的信息,忽略其他的消息。在这个例子中,我们只接收消息 hello。
我们平时会记不住朋友的电话,所以我们用通讯录给电话号码加个名字。在 Erlang 中也没有必要记住每个进程的 Pid,给其注册个名字即可以后用名字来访问之。
1>Pid=spawn(fun()->receivehello->io:format("Got hello message~n")end end).
<0.93.0>
2>register(foo,Pid).
true
3>foo!hello.
Got hello message
hello
只需调用 register(Name,Pid) 即可给任何进程注册名字。之后我们可以用该名字给进程发消息。
当我们给某进程注册了名字后,我们也能通过查找通讯录来找到其Pid。
1>register(foo,spawn(fun()->receivehello->hello end end)).
true
2>whereis(foo).
<0.102.0>
最后,一个进程可以通过调用 self() 来找到自己的Pid。
1>self().
<0.90.0>
以上6个函数就这么简单,再多也没有了。spawn, send, receive, register, whereis 和 self。就这6个函数,组成 Erlang 的世界观。Joe老爷子说,理解 Erlang 并不需要去看多少项目或者代码,仅仅搞懂这几个函数就行了。他见过有些人写过上万行 Erlang 代码但是却没有真正理解 Erlang 的世界观。别这么做,从这些简单的函数入手。