Erlang停止gen_server

3

我有一个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并停止gen_server?

谢谢。

2个回答

15

首先:您必须始终使用相同的名称来访问进程,"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这样的替代方案提供了更好的分布。

gen_server有一个特殊的函数用于执行停止操作stop/1,stop/3。http://erlang.org/doc/man/gen_server.html#stop-1 - Alexander Shavelev

1

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接