2017-09-27 6 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으로 전화해야하며, 두 번째 인수는 모니터링 할 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