2014-09-02 36 views
2

我正在閱讀Programming Erlang!在第13章的結尾,我們要建立一個保持活動過程中, 的例子喜歡:如何在Erlang中創建保持活動過程

on_exit(Pid, Fun) -> 
    spawn(fun() -> 
      Ref = monitor(process, Pid), 
      receive 
       {'DOWN', Ref, process, Pid, Info} -> 
        Fun(Info) 
      end 
    end). 
keep_alive(Name, Fun) -> 
    register(Name, Pid = spawn(Fun)), 
    on_exit(Pid, fun(_Why) -> keep_alive(Name, Fun) end). 

但當register/2on_exit/2過程中可能退出,所以顯示器會失敗之間,我改變了keep_alive/2這樣的:

keep_alive(Name, Fun) -> 
    {Pid, Ref} = spawn_monitor(Fun), 
    register(Name, Pid), 
    receive 
     {'DOWN', Ref, process, Pid, _Info} -> 
      keep_alive(Name, Fun) 
end. 

還有一個缺陷,spawn_monitor/2register/2之間,該過程可能退出。這怎麼能成功運行?謝謝。

回答

3

我不確定您是否有需要解決的問題。即使您的進程在註冊/ 2後退出,Monitor/2也會成功。 Monitor/2將發送一個'DOWN'消息,其Info組件將被noproc。每文檔:

A「DOWN」消息,如果產品管芯將被髮送到監控過程中,如果項目不存在,或者如果連接丟失到哪個項目駐留在節點。 (見http://www.erlang.org/doc/man/erlang.html#monitor-2)。

所以,在你原來的代碼

  1. 寄存器assocates名稱到PID
  2. 的Pid死亡
  3. ON_EXIT被調用,監視/ 2執行
  4. 顯示器立即發送「DOWN '由on_exit產生的函數接收到的消息
  5. 接收到的語句的Fun(Info)被執行,調用keep_alive/2

我覺得一切都很好。

0

在第二個示例中,如果進程在註冊register之前退出,將會失敗,並返回badarg。最容易的方法是圍繞註冊try ... catch並處理錯誤。

您甚至可以讓catch爲空,因爲即使註冊失敗,也會發送'DOWN'消息。

另一方面,我不會在生產系統中這樣做。如果你的員工失敗的速度如此之快,很可能問題在於它的初始化代碼,我想知道它沒有註冊並停止系統。否則,它可能會失敗並在無限循環中重新生成。

2

那麼爲什麼你不想使用erlang主管行爲?它爲創建和重新啓動保持活動進程提供了有用的功能。

在這裏看到的例子:http://www.erlang.org/doc/design_principles/sup_princ.html

+2

我覺得OP只是想了解編程二郎書行使/例子 - 我猜想,他之所以沒有得到該文本的OTP部分,但。 – Jr0 2014-09-03 20:36:31