消息传递

两个 erlang 进程可以相互通信,这也称为消息传递
此过程是异步的,其形式是发送过程在发送消息后不会停止。

发送消息

这可以通过构造 Pid ! Message 来实现,其中 Pid 是有效的进程标识符(pid),Message 是任何数据类型的值。

每个进程都有一个邮箱,其中包含收到的订单中收到的邮件。这个邮箱可以通过 flush/0 功能的构建清空。

如果将消息发送到非现有进程,则将丢弃该消息而不会出现任何错误!

示例可能如下所示,其中 self/0 返回当前进程的 pid,pid/3 创建 pid。

1> Pidsh = self().
<0.32.0>
2> Pidsh ! hello.
hello
3> flush().
Shell got hello
ok
4> <0.32.0> ! hello.
* 1: syntax error before: ’<’
5> Pidsh2 = pid(0,32,0).
<0.32.0>
6> Pidsh2 ! hello2.
hello2
7> flush().
Shell got hello2
ok

也可以使用 Pid3!Pid2!Pid1!Msg 一次向多个进程发送消息。

接收消息

可以使用 receive 构造处理收到的消息。

receive
  Pattern1            -> exp11, .., exp1n1;
  Pattern2 when Guard -> exp21, .., exp2n2;
  ...
  Other               -> exp31, .., exp3n3;
  ...
  after Timeout       -> exp41, .., exp4n4
end

Pattern 将与从第一个和最早的消息开始的邮箱中的消息进行比较。
如果模式匹配,则从邮箱中删除匹配的消息,并评估子句主体。

也可以使用 after 构造定义超时。
Timeout 要么是以毫秒为单位的等待时间,要么是原子 infinity

receive 的返回值是最后一个被评估的子句体。

示例(计数器)

带有消息传递的(非常)简单计数器可能如下所示。

-module(counter0).
-export([start/0,loop/1]).

% Creating the counter process.
start() ->
    spawn(counter0, loop, [0]).

% The counter loop.
loop(Val) ->
    receive
        increment ->
           loop(Val + 1)
    end.

与柜台互动。

1> C0 = counter0:start().
<0.39.0>
2> C0!increment.
increment
3> C0!increment.
increment