Erlang停止gen_server

时间:2011-04-20 06:44:19

标签: erlang gen-server

我有gen_server:

start(UserName) ->
    case gen_server:start({global, UserName}, player, [], []) of
    {ok, _} ->
        io:format("Player: " ++ UserName ++ " started");
    {error, Error} ->
        Error
    end
    ...

现在我想写函数来停止这个gen服务器。我有:

stop(UserName) ->
    gen_server:cast(UserName, stop).

handle_cast(stop, State) ->
    {stop, normal, State};
handle_cast(_Msg, State) ->
    {noreply, State}.

我跑了:

start("shk").
Player: shk startedok
stop(shk).
ok
start("shk").
{already_started,<0.268.0>}

可是:

stop(player).
ok

是工作。

如何按名称运行gen_server并按名称停止?

谢谢。

2 个答案:

答案 0 :(得分:13)

首先:您必须始终使用相同的名称来处理流程,"foo"foo是不同的,所以首先要有严格的命名约定。

第二:使用全局注册的流程时,还需要使用{global, Name}来解决流程。

在我看来,你还应该将stop函数转换为使用gen_server:call,这将阻止并让你从gen_server返回一个值。一个例子:

stop(Name) ->
    gen_server:call({global, Name}, stop).

handle_call(stop, _From, State) ->
    {stop, normal, shutdown_ok, State}

这会将shutdown_ok返回给调用者。

有了这个说法,global模块相当有限,像gproc这样的替代方案提供了更好的分发。

答案 1 :(得分:1)

我没有面向我的文档,但我的猜测是你需要将用户名包装在gen_server cast中的全局元组中。