節(jié)選自:https://www.sohu.com/a/244980510_473282
Erlang 的世界和我們的真實世界很像。每個 Erlang 進(jìn)程維護(hù)著自己獨有的內(nèi)存,別的進(jìn)程無法訪問其內(nèi)部狀態(tài),除非它們互發(fā)消息進(jìn)行交流。所有的消息傳遞都是異步的,就像我們的現(xiàn)實世界。
1>spawn(foo,hello,[]).
<0.70.0>
這樣就會創(chuàng)建一個新的進(jìn)程,調(diào)用foo:hello()。進(jìn)程一旦執(zhí)行完這個函數(shù)就會死掉,將所有分配到的內(nèi)存還給BEAM。
如果你想創(chuàng)建兩個進(jìn)程同時做事,只需spawn兩次:
1>spawn(foo,hello,[]).
<0.70.0>
2>spawn(foo,hello,[]).
<0.71.0>
這將創(chuàng)建兩個進(jìn)程并發(fā)調(diào)用foo:hello()。這就是 Erlang 的并發(fā)模型——也叫參與者模式 (Actor model)。
如果你想整100個進(jìn)程同時做事,調(diào)用spawn 100次即可。簡單粗暴。
現(xiàn)在我們知道如何創(chuàng)建進(jìn)程,接下來是給它發(fā)消息。
1>Pid=spawn(foo,loop,[]).
<0.80.0>
2>Pid!hello.
hello
這里我們啟動一個進(jìn)程調(diào)用 foo:loop()。我們假設(shè)這個loop函數(shù)會遞歸調(diào)用自己,這樣我們的進(jìn)程不會一下就死掉。spawn 會返回一個進(jìn)程ID <0.80.0>,我們將其綁定到 Pid 變量中,并向其發(fā)個消息 hello。 Erlang 里用驚嘆號 ! 發(fā)消息。好了,以上就是異步消息發(fā)送。這也是 Erlang 中兩個進(jìn)程之間交流的唯一手段。
當(dāng)消息被發(fā)給某進(jìn)程后,該進(jìn)程如何收消息呢?
1>Pid=spawn(fun()->
1>receive
1>hello->io:format("Got hello message~n")
1>end
1>end).<0.86.0>
2>Pid!hello.
Gothellomessage
hello
用 receive 來收消息。你可以在這里用模式匹配來匹配你想要接收的信息,忽略其他的消息。在這個例子中,我們只接收消息 hello。
我們平時會記不住朋友的電話,所以我們用通訊錄給電話號碼加個名字。在 Erlang 中也沒有必要記住每個進(jìn)程的 Pid,給其注冊個名字即可以后用名字來訪問之。
1>Pid=spawn(fun()->receivehello->io:format("Got hello message~n")endend).
<0.93.0>
2>register(foo,Pid).
true
3>foo!hello.
Gothellomessage
hello
只需調(diào)用 register(Name,Pid) 即可給任何進(jìn)程注冊名字。之后我們可以用該名字給進(jìn)程發(fā)消息。
當(dāng)我們給某進(jìn)程注冊了名字后,我們也能通過查找通訊錄來找到其Pid。
1>register(foo,spawn(fun()->receivehello->helloendend)).
true
2>whereis(foo).
<0.102.0>
最后,一個進(jìn)程可以通過調(diào)用 self() 來找到自己的Pid。
1>self().
<0.90.0>
以上6個函數(shù)就這么簡單,再多也沒有了。spawn, send, receive, register, whereis 和 self。就這6個函數(shù),組成 Erlang 的世界觀。