2010-11-09 24 views

cevap

12

veri girişi '$ancestors' altında (herhangi bir işlem proc_lib ile kökenli ait) işlem sözlükte gizlidir: Burada

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

bize {dictionary,[{'$ancestors',[<0.31.0>]}, olduğunu ilgilendiren hat

.

Bu, kendinizi nadiren kullanmanız için bir nedene sahip olmanız gereken türden bir şey olduğunu unutmayın. Bildiğim kadarıyla, daha önce sahip olduğunuz herhangi bir kod için iç gözlemden ziyade denetim ağaçlarındaki temiz sonlandırmayı işlemek için kullanılır. Dikkatli tutun.

OTP'nin mantıklı içgüdüleriyle uğraşmadan işleri yapmanın daha temiz bir yolu, 'un denetleyicinin, kendi pid'ını, başlatılırken işlemin bir argümanı olarak geçirmesini sağlamaktır. Bu, kodunuzu okuyan insanlar için çok daha az kafa karıştırıcı olmalıdır. Yanlış yapmak istiyorsanız

+0

Evet, bu iyi bir fikir gibi görünüyor. –

+3

Ben de amiri pid geçişi ile giderdim. Uygulanması ve sürdürülmesi daha basittir. –

1

, burada çözüm:

%% @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).