0

受信したメッセージに応答するいくつかのプロセスを生成したいと思います。これは簡単です。ただし、別のプロセスの出力をブロックできるプロセスも必要です。

別の言語では、メッセージを送信する前にフラグを設定し、そのフラグのステータスを確認する場合があります。しかし、Erlangには可変変数がないので、どうすればそれを達成できますか?

receive抑制メッセージを監視するために、パターンをに追加することはできます。次にどうしたらいいのかわからない。

これだけにETSテーブルを使用するというアイデアは、優れた分散モデルを壊すため、あまり好きではありません。同様に、並行性の問題についてはあまり心配していませんが、これを最も適切な方法で設計したいと思います。

4

1 に答える 1

2

各エコーサーバーは、現在ミュートされているかどうかを示す独自の状態を持つことができます。他のプロセスは、ミュート/ミュート解除メッセージでその状態を切り替えることができます。メッセージに応答する前に、エコーサーバーは状態をチェックして適切に動作します。

例えば:

1> {ok, Pid} = echo:start_link().
{ok,<0.99.0>}
2> echo:echo(Pid, "this message will be echoed.").
#Ref<0.0.0.443>
3> echo:echo(Pid, "as will this message..").
#Ref<0.0.0.447>
4> echo:mute(Pid).
ok
5> echo:echo(Pid, "this message will not.").
#Ref<0.0.0.457>
6> echo:unmute(Pid).
ok
7> echo:echo(Pid, "but this one will..").
#Ref<0.0.0.461>
8> flush().
Shell got {#Ref<0.0.0.443>,"this message will be echoed."}
Shell got {#Ref<0.0.0.447>,"as will this message.."}
Shell got {#Ref<0.0.0.461>,"but this one will.."}
ok
9> echo:stop(Pid).
ok

コード:

-module(echo).

-behaviour(gen_server).

%% API
-export([start_link/0,
     echo/2,
     mute/1,
     unmute/1,
     stop/1]).

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

-define(SERVER, ?MODULE). 

-record(state, {mute=false}).

%%%===================================================================
%%% API
%%%===================================================================

start_link() ->
    gen_server:start_link(?MODULE, [], []).

echo(Pid, Msg) ->
    Ref = make_ref(),
    gen_server:cast(Pid, {echo, self(), Ref, Msg}),
    Ref.

mute(Pid) ->
    gen_server:cast(Pid, mute).

unmute(Pid) ->
    gen_server:cast(Pid, unmute).

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

%%%===================================================================
%%% gen_server callbacks
%%%===================================================================

init([]) ->
    {ok, #state{}}.

handle_call(_Request, _From, State) ->
    Reply = ok,
    {reply, Reply, State}.

handle_cast({echo, From, Tag, Msg}, #state{mute=false} = State) ->
    From ! {Tag, Msg},
    {noreply, State};
handle_cast({echo, _From, _Tag, _Msg}, #state{mute=true} = State) ->
    {noreply, State};
handle_cast(mute, State) ->
    {noreply, State#state{mute=true}};
handle_cast(unmute, State) ->
    {noreply, State#state{mute=false}};
handle_cast(stop, State) ->
    {stop, normal, State};
handle_cast(_Msg, State) ->
    {noreply, State}.

handle_info(_Info, State) ->
    {noreply, State}.

terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.
于 2012-04-15T19:00:35.573 に答える