Erlang注册进程如何使用 ?

Posted 程序大官猿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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().


以上是关于Erlang注册进程如何使用 ?的主要内容,如果未能解决你的问题,请参考以下文章

如何连接到已注册的节点(Erlang)并从另一个 erlang 应用程序中使用它

如何使用非 jvm 语言(例如 erlang、php)注册 Eureka?

在 Erlang 中作为进程生成的函数内部定义的函数

Erlang:控制Erlang进程崩溃时如何使连接的外部OS进程自动死亡?

如何连接到已注册的节点(Erlang)并从 Ejabberd 使用它

如何在Erlang中动态创建原子?