可以通过Pid在gen_server进程中调用函数

时间:2016-03-31 13:26:25

标签: erlang otp

如果我有一组名为lock的gen服务器,我可以调用一个函数说

hello() -> io:format("Hello, world!~n").

来自gen_server的各个进程的Pid而不是泛型lock:hello().

我尝试了Pid=<0.91.0>(所以当我在我的主管中开始一个chid时,Pid会返回)和Pid:hello()。给出一个不好的论点是不可能做到的?

发送消息代替调用该函数是否更好?

3 个答案:

答案 0 :(得分:5)

你可以调用gen_server:call(Pid,TuplePatternThatMatchesOnCallback)

-behaviour(gen_server).

%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
         terminate/2, code_change/3]).

...

hello() ->
  gen_server:call(Pid, hello).


handle_call(hello, _From, _State) ->
    Reply = io:format("Hello, world!~n")
    {reply, Reply, State}.

Erlang中没有Pid:Function API。

在这两种情况下,调用gen服务器将序列化调用,前提是您正在使用gen_server API。但是通过函数调用,您可以选择同步回复。

如果hello刚刚放在gen_server模块中(没有gen_server:call),它将在调用进程的上下文中执行,而不是gen_server one。

答案 1 :(得分:3)

当您调用gen_server模块中的函数时,该函数不会在gen_server进程中执行。它在调用者进程中执行。

如果你想让gen_server进程做某事,你应该使用gen_server:call或gen_server:cast函数:

例如,gen_server:call / 2函数将带有一个pid和一条将与该调用一起发送的消息。然后gen_server将在gen_server进程中运行它的handle_call函数。

通常情况下,您将在同一模块中具有定义将执行gen_server:gen_server的gen_server的函数,以便调用者不必关心。这为其他人创建了一个干净的API,并隐藏了gen_server特定的东西。

将所有部分组合在一起可能有点棘手但是一旦你拥有它就很简单。看看LYSE的这一章: http://learnyousomeerlang.com/clients-and-servers

答案 2 :(得分:1)

您可以从任何地方调用函数hello。如果从1000个进程中调用它1000次,则每个进程将并行执行该函数而不会相互干扰。您只需从每个进程中调用它lock:hello().,因此您可以调用特定模块hello中定义的特定函数lock,该函数将采用零参数。

可能你的问题中没有提到的东西?