3

Erlang のプロセスは、別のプロセスとのリンクを呼び出すlink/1spawn_link、リンクを作成します。私が取り組んでいる最近のアプリケーションでは、プロセスが特定のインスタンスでリンクされている他のプロセスの数を知ることができるかどうかに興味がありました。これは可能ですか?彼らはBIFですか?

また、リンクされたプロセスが死んだ場合、リンクされたプロセスの数を知ることができれば、この数はランタイム システムによって自動的に減らされるのではないでしょうか。このようなメカニズムはParent-Child、Erlang の並行プログラムで関係を処理するのに理想的supervisorsです。

リンクされたプロセスが停止するたびに、この値が自動的に減少するように、Erlang プロセスがout-of-the-boxおそらく BIF を介してリンクされたプロセスの数を知ることは可能under-the-hoodですか :)?


この質問を少し拡張するために、 を介して何千ものメッセージを処理する gen_server を考えてみましょうhandle_info。この部分では、dispatch子プロセスがタスクを受け取るとすぐにそれを処理します。これの目的はserver loop、次の要求を処理するためにすぐに戻ることを確認することです。これで、子プロセスはタスクを非同期的に処理し、終了する前に要求元に応答を返します。続行する前に、この質問とその回答を参照してください。

ここで、gen_server によって生成されたすべての子プロセスに対してリンクが作成され、このリンクをカウンターとして使用したいとします。私は知っています、私は知っています、誰もが「なぜgen_serverを使わないのか」のようになるでしょうState、たとえばカウンターを運び、それに応じてそれを増減しますか?" :) gen_server のどこかに、次のものがあります。

handle_info({Sender,Task},State)->
    spawn_link(?MODULE,child,[Sender,Task]),
    %%  At this point, the number of links to the gen_server is incremented
    %%  by the run-time system
    {noreply,State};
handle_info( _ ,State) -> {noreply,State}.

この子は次のように続けます。

child(Sender,Task)->
    Result = (catch execute_task(Task)),
    Sender ! Result,
    ok. %% At this point the child process exits, 
        %% and i expect the link value to be decremented

最後に、gen_server には次のような呼び出しが公開されています。

get_no_of_links()-> gen_server:call(?MODULE,links).
handle_call(links, _ ,State)->
    %% BIF to get number of instantaneous links expected here
    Links = erlang:get_links(), %% This is fake, do not do it at home :)
    {reply,Links,State};
handle_call(_ , _ ,State)-> {reply,ok,State}.

さて、ある人は自分自身に自問するかもしれません。

通常、gen_server State で整数を作成してから自分で作成するか、少なくとも gen_server の handle_info 型{'EXIT',ChildPid,_Reason}を作成すると、サーバーはそれに応じて動作します。私の考えでは、リンクの数を知ることができれば、これを使用して(特定の時点で)、まだ動作中の子プロセスの数を知ることができます。これは実際にサーバーの負荷を予測するのに役立ちます。

4

2 に答える 2

8

process_info のマニュアルから:

{links, Pids}: Pids は、プロセスがリンクしているプロセスを含む pid のリストです。

3> process_info(self(), links).
{links,[<0.26.0>]}
4> spawn_link(fun() -> timer:sleep(100000) end).
<0.38.0>
5> process_info(self(), links).                 
{links,[<0.26.0>,<0.38.0>]}

リンクされたプロセスの数をカウントするために使用できると思います

于 2012-12-10T12:56:58.033 に答える
1

プロセスを実行し、リンクされたプロセスが終了するたびに到着するprocess_flag(trap_exit, true)フォームのメッセージをリッスンする必要があります。{'EXIT', Pid, Reason}終了をトラップしない場合、デフォルトの動作では、リンクの反対側が終了したときに、リンクされたプロセスが終了します。

プロセスがリンクを追加するタイミングをリッスンするには、case process_info(self(), links) of {links, L} -> length(L) endまたはを使用できlength(element(2, process_info(self(), links))ますが、リンクが追加されるたびにプロセスに通知する方法がないため、これを定期的に再実行する必要があります。

OTP ガイドラインに従うプロセスは、それにリンクされているプロセスの数を知る必要はありません。

于 2012-12-10T13:13:59.597 に答える