Frage

Gibt es Funktionen, die ein OTP-Prozess erlauben würde, die pid seiner Vorgesetzten zu finden?

War es hilfreich?

Lösung

Die Daten werden in dem Prozess Wörterbuch versteckt (ein Prozesses mit proc_lib gelaicht) unter dem Eintrag '$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,[]}]

Hier ist die Linie, die Interesse sind wir {dictionary,[{'$ancestors',[<0.31.0>]},.

Beachten Sie, dass dies die Art von Sachen, die man nur selten einen Grund, sich zu verwenden haben. Soweit ich weiß, ist es meist saubere Terminierung in Aufsicht Bäume anstatt Selbstbeobachtung für Sie haben, was auch immer Code verwendet zu behandeln. Handle with care.

Eine sauberere Weg, Dinge zu tun, ohne mit OTP vernünftige Innereien zu Unordnung wäre haben die Vorgesetzten seine eigene pid als Argument für den Prozess übergeben, wenn es zu starten. Dies sollte weit weniger verwirrend für die Menschen, die Ihren Code gelesen werden.

Andere Tipps

Wenn Sie es falsch machen wollen, hier ist unsere Lösung:

%% @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).
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top