1

こんにちは、私は Erlang の初心者で、プロセスについて学び始めたところです。ここに、典型的なプロセス ループがあります。

loop(X,Y,Z) ->
    receive
        {do} ->
            NewX = X+1,
            NewY = Y+1,
            NewZ = Z+1,

            Product = NewX * NewY * NewZ,

            % do something

            loop(NewX,NewY,NewZ)
    end.

Product関数から最新の値を取得するにはどうすればよいget_product()ですか? メッセージの受け渡しが論理的なオプションであることはわかっていますが、値を抽出するためのより最適な方法はありますか?

4

2 に答える 2

2

これがあなたが望むものだと思いました

-module(lab).

-compile(export_all).

start() ->
    InitialState = {1,1,1},
    Pid = spawn(?MODULE, loop, [InitialState]),
    register(server, Pid).

loop(State) ->
    {X, Y, Z} = State,
    receive
        tick ->
            NewX = X+1,
            NewY = Y+1,
            NewZ = Z+1,
            NewState = {NewX, NewY, NewZ},
            loop(NewState);
        {get_product, From} ->
            Product = X * Y * Z,
            From ! Product,
            loop(State);
        _ ->
            io:format("Unknown message received.~n"),
            loop(State)
    end.

get_product() ->
    server ! {get_product, self()},
    receive
        Product ->
            Product
    end.

tick() ->
    server ! tick.

Erlang シェル内から:

1> c(lab).
{ok,lab}
2> lab:start().
true
3> lab:get_product().
1
4> lab:tick().       
tick
5> lab:get_product().
8
6> lab:tick().       
tick
7> lab:tick().
tick
8> lab:get_product().
64
于 2013-09-15T07:19:50.797 に答える
2

以下は、私が認識している Erlang プロセス間で通信する方法と、それらの相対的なパフォーマンスに関する私の (おそらく間違った) 評価です。

  1. メッセージの受け渡し。この方法は、ほとんどのニーズに適しています。実際にどのように実装されているかはわかりませんが、私の観点からは、ポインターをキューに入れ、それを取得するのと同じくらい高速である必要があります。
  2. socketsfilespipesなどの外部メソッド。これらの方法は、解決する問題、ソリューション、およびプログラムが実行される環境に応じて、異なるノード間で通信する場合により高速になる場合があります。Erlang でのノード間通信は TCP 接続を介して行われるため、自己記述コードを使用する場合TCP ソケットを介して通信するには、Erlang の実装よりも優れたパフォーマンスを発揮できるように努力する必要があります。
  3. ETSDets。これらのメソッドは、可能な限り最良の実装を前提として、メッセージ パッシング (ETS) またはファイル (Dets) よりも高速ではありません。
  4. NIF。NIF ライブラリに値を保存するメソッドと、値を取得するメソッドを 1 つずつ記述できます。これは、値を変数に保存し、必要に応じて戻すことができ、.NET でのパターン マッチングのオーバーヘッドがないため、メッセージ パッシングよりも優れたパフォーマンスを発揮する可能性がありますreceive
  5. ディクショナリを処理しますerlang:process_info(Pid, dictionary)callを使用して別のプロセス ディクショナリを取得できますPidプロセスでは、call を使用してそのディクショナリに値を入れることができput(Key, Value)ます。

また、Erlang アプリケーションを高速化したい場合は、HiPEを調べてください。役立つかもしれません。

メッセージパッシングからこのリストの何かに切り替えて速度を上げる前に、まずそれを測定する必要があります!

于 2013-09-15T14:49:16.370 に答える