3

私はgen_serverを持っています:

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

今、私はこの世代のサーバーを停止する関数を書きたいと思います。私は持っています:

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を名前で実行し、名前で停止するにはどうすればよいですか?

ありがとうございました。

4

2 に答える 2

14

最初に: プロセスのアドレス指定には常に同じ名前を使用する必要があり"foo"fooそれらは異なるため、厳密な命名規則を用意することから始めます。

{global, Name}2 番目: グローバルに登録されたプロセスを使用する場合は、プロセスのアドレス指定にも使用する必要があります。

stop私の意見では、関数を useに変換する必要もあります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ははるかに優れた配布を提供します.

于 2011-04-20T07:22:16.693 に答える
1

目の前にドキュメントはありませんが、gen_server キャスト内のグローバル タプルでユーザー名をラップする必要があると思います。

于 2011-04-20T07:21:51.247 に答える