Erlang中的注册进程使用实例
之前看到 Erlang 中的注册进程时,对注册并不理解,主要是不理解注册的原子的作用域。刚才突然想明白了:
代码如下:
注册进程关联的原子具有全局作用域
也就是说关联了注册进程之后的原子可以全局被使用
Erlang 中的并发机制是通过消息邮箱实现的,进程间进行通讯的方式只有消息邮箱,而进程间通讯需要知道进程的进程号,而使用 spawn 产生新进程时会返回新进程的进程号供使用。
一个最简单的进程间通信的程序如下
代码如下:
-module(test). start() -> spawn(?MODULE, loop, []). loop() -> io:format("Waiting for new message.~n"), receive M -> io:format("New message: ~p~n", [M]) end, loop().
在 Erlang Shell 中使用 c(test) 编译这个模块,之后就可以简单的使用了.
在下面的代码中,语句前面的注释表示解释,语句后面的注释表示输出值, % => 后面的值表示语句的返回值
代码如下:
% 编译这个模块 c(test). % 开启无限循环 Pid = test:start(). % Waiting for new message. % 新进程 spawn 后立刻运行 % => <0.35.0> % 返回新进程的进程号 % 向进程发送消息 Pid ! 'message'. % New message: message % 接收到消息 % Waiting for new message. % 继续接收消息 % => message % 语句返回值,而非进程返回消息
为了用户不用每次都 Pid ! 'message',可以加入一个 call 方法进行包装一下。
代码如下:
call(Pid, M) -> Pid ! M.
这样就可以使用 test:call(Pid, 'message') 发送消息了。
但是这样写还有个明显的弊端,调用 call 时需要 Pid 参数,但是又不能去掉,因为需要进程号才能通信,所以使用时需要用户维护一个进程号。
而 Erlang 提供了注册进程的机制用来把原子关联到进程中,可以解决这个问题
使用 register(atom, Pid) 可以将 atom 关联到进程号为 Pid 的进程上,这个原子就
修改上面的 start 函数为
代码如下:
start() -> register(testp, spawn(?MODULE, loop, [])).
这样,新的进程将关联到原子 testp,此时原子就可以当作 Pid 那样使用 "消息发送操作符" !
代码如下:
testp ! 'message'
于是可以修改上面的 call 函数,去掉 Pid 参数,而使用关联后的原子,这个关联后的原子不止在模块内有效,在全局作用域中都是有效的。
代码如下:
call(M) -> testp ! M.
因此使用注册进程修改后的程序如下
代码如下:
-module(test). start() -> register(testp, spawn(?MODULE, loop, [])). loop() -> io:format("Waiting for new message.~n"), receive M -> io:format("New message: ~p~n", [M]) end, loop(). call(M) -> testp ! M.
注册相关的 BIF
代码如下:
% 注册 atom 到 Pid register(atom, Pid). % 取消 atom 的注册 unregister(atom). % 返回 atom 关联的进程号,如果未关联,返回 undefined whereis(atom). % 返回系统中所有已注册的进程名 registered().
相关推荐
chenpro 2020-08-09
NVEFLY 2020-07-04
liym 2020-06-21
OnMyHeart 2020-06-06
天空windy 2020-06-03
87447007 2020-05-16
OnMyHeart 2020-05-09
NVEFLY 2020-04-17
M守护神 2020-03-28
大史哥哥 2020-03-07
wbingyang 2020-02-27
liym 2020-02-22
zhoucheng0 2020-02-19
wbingyang 2020-02-14
OnMyHeart 2020-01-14
OnMyHeart 2020-01-08
大史哥哥 2019-12-31
wbingyang 2019-12-31