Domanda

Ci sono funzioni che permettano un processo OTP per trovare il pid del suo supervisore?

È stato utile?

Soluzione

I dati è nascosta nel dizionario processo (di qualsiasi processo generato con proc_lib) sotto la '$ancestors' voce:

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,[]}]

Qui la linea che ci interessa è {dictionary,[{'$ancestors',[<0.31.0>]},.

Si noti che questo è il genere di cose raramente si dovrebbe avere alcun motivo per utilizzare da soli. Per quanto ne so, è in gran parte utilizzato per gestire la terminazione pulita in alberi di supervisione piuttosto che l'introspezione per qualsiasi codice che avete. Maneggiare con cura.

Un modo pulito di fare le cose senza fare confusione con interiora sensibili di OTP sarebbe quello di ha il supervisore passare il proprio PID come argomento per il processo quando si inizia è . Questo dovrebbe essere molto meno confusione per le persone che ti leggono il vostro codice.

Altri suggerimenti

Se si vuole fare male, ecco la nostra soluzione:

%% @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).
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top