注册进程
上面的例子中,因为 “Pong” 在 “ping” 进程开始前已经创建完成,所以才能将 “pong” 进程的进程标识符作为参数传递给进程 “ping” 这也就说,“ping” 进程必须通过某种途径获得 “pong” 进程的进程标识符后才能将消息发送 “pong” 进程 然而,某些情况下,进程需要相互独立地启动,而这些进程之间又要求知道彼此的进程标识符,前面提到的这种方式就不能满足要求了
因此,Erlang 提供了为每个 进程 绑定 一个 名称 的机制,这样进程间通信就可以通过进程名来实现,而不需要知道进程的进程标识符了。为每个进程注册一个名称需要用到内置函数 register :
register(some_atom, Pid)
这一次,为 “pong” 进程赋予了一名进程名称 pong :
-module(register). -export([start/0, ping/1, pong/0]). ping(0) -> pong ! finished, io:format("ping finished~n", []); ping(N) -> pong ! {ping, self()}, receive pong -> io:format("Ping received pong~n", []) end, ping(N - 1). pong() -> receive finished -> io:format("Pong finished~n", []); {ping, Ping_PID} -> io:format("Pong received ping~n", []), Ping_PID ! pong, pong() end. start() -> register(pong, spawn(register, pong, [])), spawn(register, ping, [3]).
start/0 函数中创建 “pong” 进程的同时还 赋予 了它一个名称 pong :
register(pong, spawn(tut16, pong, [])),
在 “ping” 进程中使用了这个名称来发送消息:
ping(N) -> pong ! {ping, self()},
因此 ping 函数也不再需要Pong_Id 作为参数了,所以ping/2 变成了 ping/1
-export([start/0, ping/1, pong/0]).
测试下:
7> register:start() .
Pong received ping
<0.109.0>
Ping received pong
Pong received ping
Ping received pong
8>
Pong received ping
Ping received pong
ping finished
Pong finished