Как найти руководителя процесса OTP?

Существуют ли функции, которые позволили бы процессу OTP найти pid своего супервизора?


person Alexey Romanov    schedule 09.11.2010    source источник
comment
Понятия не имею, но на самом деле вы можете получить связанные процессы, и руководитель является одним из них.   -  person ZeissS    schedule 09.11.2010


Ответы (2)


Данные скрыты в словаре процессов (любого процесса, порожденного 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 в качестве аргумента процессу при его запуске. Это должно сбивать с толку людей, которые будут читать ваш код.

person I GIVE TERRIBLE ADVICE    schedule 09.11.2010
comment
Я бы также пошел с пропуском pid супервизора. Его проще реализовать и поддерживать. - person I GIVE CRAP ANSWERS; 10.11.2010

Если вы хотите сделать это неправильно, вот наше решение:

%% @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).
person YOUR ARGUMENT IS VALID    schedule 10.11.2010