OTPプロセスの監督者を見つける方法は?
-
29-09-2019 - |
質問
OTPプロセスがスーパーバイザーのPIDを見つけることを可能にする機能はありますか?
解決
データはプロセス辞書に隠されています(任意のプロセスが生み出されました proc_lib
)エントリの下 '$ancestors'
:
1> proc_lib:spawn(fun() -> timer:sleep(infinity) end).
<0.33.0>
2> i(0,33,0).
[{current_function,{timer,sleep,1}},
{initial_call,{proc_lib,init_p,3}},
{status,waiting},
{message_queue_len,0},
{messages,[]},
{links,[]},
{dictionary,[{'$ancestors',[<0.31.0>]},
{'$initial_call',{erl_eval,'-expr/5-fun-1-',0}}]},
{trap_exit,false},
{error_handler,error_handler},
{priority,normal},
{group_leader,<0.24.0>},
{total_heap_size,233},
{heap_size,233},
{stack_size,6},
{reductions,62},
{garbage_collection,[{min_bin_vheap_size,46368},
{min_heap_size,233},
{fullsweep_after,65535},
{minor_gcs,0}]},
{suspending,[]}]
ここに私たちが興味を持っている線があります {dictionary,[{'$ancestors',[<0.31.0>]},
.
これは、自分自身を使用する理由はめったにないようなものであることに注意してください。私の知る限り、それは主に、あなたが持っているコードの内省ではなく、監督木のきれいな終了を処理するために使用されています。取扱注意。
OTPの賢明な内臓を台無しにせずに物事を行うよりクリーンな方法は スーパーバイザーに、開始時にプロセスへの議論として独自のPIDを渡させてもらいます. 。これは、あなたのコードを読む人にとってははるかに混乱しているはずです。
他のヒント
あなたがそれを間違えたいなら、ここに私たちの解決策があります:
%% @spec get_ancestors(proc()) -> [proc()]
%% @doc Find the supervisor for a process by introspection of proc_lib
%% $ancestors (WARNING: relies on an implementation detail of OTP).
get_ancestors(Pid) when is_pid(Pid) ->
case erlang:process_info(Pid, dictionary) of
{dictionary, D} ->
ancestors_from_dict(D);
_ ->
[]
end;
get_ancestors(undefined) ->
[];
get_ancestors(Name) when is_atom(Name) ->
get_ancestors(whereis(Name)).
ancestors_from_dict([]) ->
[];
ancestors_from_dict([{'$ancestors', Ancestors} | _Rest]) ->
Ancestors;
ancestors_from_dict([_Head | Rest]) ->
ancestors_from_dict(Rest).
所属していません StackOverflow