我有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并按名称停止?
谢谢。
答案 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中的全局元组中。