2017-09-27 5 views
3

まだJoeの本を読んでいて、モニター全般と特にspawn_monitorを完全に理解するのは苦労しています。ここに私のコードがあります。この練習では、5秒ごとにハートビートを印刷するジョブを開始する関数を記述してから、上記のプロセスを監視して再起動する関数を作成するように求めています。私のモニタでは、プロセスの終了を検出することさえできないので、私は再起動の部分には行きませんでした。erlang spawn_monitorの正しい使い方

39> c("ex.erl").      
{ok,ex} 
40> ex:create_reg_keep_alive(myjob). 
{<0.147.0>,myjob} 
I'm still alive      
I'm still alive   
41> ex:my_monitor(myjob). 
monitoring PID <0.147.0> 
{<0.149.0>,#Ref<0.230612052.2032402433.56637>} 
I'm still alive 
I'm still alive      
42> exit(whereis(myjob), stop). 
true 
43> 

それは確かloop_5_print「労働者」を停止 - が、モニタがプリントになっていた行があります:

% simple "working" loop 
loop_5_print() -> 
    receive 
    after 5000 -> 
      io:format("I'm still alive~n"), 
      loop_5_print() 
    end. 

% function to spawn and register a named worker 
create_reg_keep_alive(Name) when not is_atom(Name) -> 
    {error, badargs}; 
create_reg_keep_alive(Name) -> 
    Pid = spawn(ex, loop_5_print, []), 
    register(Name, Pid), 
    {Pid, Name}. 

% a simple monitor loop 
monitor_loop(AName) -> 
    Pid = whereis(AName), 
    io:format("monitoring PID ~p~n", [Pid]), 
    receive 
     {'DOWN', _Ref, process, Pid, Why} -> 
      io:format("~p died because ~p~n",[AName, Why]), 
      % add the restart logic 
      monitor_loop(AName) 
    end. 

% function to bootstrapma monitor 
my_monitor(AName) -> 
    case whereis(AName) of 
     undefined -> {error, no_such_registration}; 

     _Pid -> spawn_monitor(ex, monitor_loop, [AName]) 
    end. 

そして、ここでは私は中で遊びましたか?私が見ている唯一の説明は、この方法で終了したプロセスから出されたメッセージは、モニタループ内の一致するパターンではないということです。を受け取ります。しかし、それは、この章の本の中で紹介したパターンのみですので、私はこの説明を買っていないよ...

答えて

7

spawn_monitorはあなたがここに欲しいものではありません。 spawn_monitorはプロセスを生成し、すぐにプロセスの監視を開始します。生成されたプロセスが終了すると、spawn_monitorというプロセスはプロセスが停止したというメッセージを受け取ります。 DOWNメッセージを受信するプロセスからerlang:monitor/2にコールする必要があります.2番目の引数は監視するPidです。

monitor(process, Pid), 

後:

ジャスト追加

Pid = whereis(AName), 

、それが動作します:

1> c(ex). 
{ok,ex} 
2> ex:create_reg_keep_alive(myjob). 
{<0.67.0>,myjob} 
I'm still alive 
I'm still alive 
I'm still alive 
3> ex:my_monitor(myjob). 
monitoring PID <0.67.0> 
{<0.69.0>,#Ref<0.2696002348.2586050567.188678>} 
I'm still alive 
I'm still alive 
I'm still alive 
4> exit(whereis(myjob), stop). 
myjob died because stop 
true 
monitoring PID undefined 
+0

私の良さ、あなたは絶対的に正しいです。私はモニターのセマンティクスと混乱し続ける。私はすでにspawn_monitor/3が "モニターを作成する"という意味ではなく、 "この計算を作成してモニターする"という意味ではないことを認識していますが、それを実現することなく私の誤解に戻しました。 – alexakarpov

+1

もう一度仲間に感謝します - 私のエラーを指摘して、私は解決できました、そして私の解決策をリファクタリングしました。私はErlang fooが私の中でより強くなっていると感じています=) – alexakarpov

関連する問題