2016-09-21 44 views
3

Elixir的Mix and OTP Guide Chapter GenServer解釋瞭如何使用GenServer實施註冊服務器控股代理。爲什麼在執行GenServer時更好地跟蹤#Reference而不是#PID?

每個座席的PID保存在一張地圖中,其中的密鑰是由客戶端提供的座席名稱,值是座席的PID。

爲了避免保持到死劑的引用,導向提出了使用Process.monitor/1監視新創建的代理,並通過添加新的地圖略微修改的狀態下,稱爲refs,含有參考文獻(通過Process.monitor/1返回的值)作爲鍵和代理商的名稱作爲值。它還顯示如何使用handle_info/2更新refs來處理監控消息。

Process.monitor/1接收PID(例如#PID<0.66.0>)作爲參數並返回參考(例如#Reference<0.0.0.551>)。由handle_info/2捕獲的:DOWN消息提供了PID和參考。

既然我們都知道這兩個值:使用引用作爲refs中使用PID的鍵的好處是什麼?

回答

2

這是一致性問題。儘管您只監視進程,但沒有任何區別。但底層:erlang.monitor/2只能監視不到進程:有端口等,基本沒有PID

從DOC:

Object

被監測實體,從而引發該事件。在監視本地進程或端口時,Object將等於正在監視的pid()port()。當按名稱監視進程或端口時,Object將具有格式{RegisteredName, Node},其中RegisteredName是與monitor/2調用一起使用的名稱,而Node是本地或遠程節點名稱(對於由名稱監控的端口,Node始終是本地節點名稱)。

總結:Reference是一個被監視的實體。它可能是一個過程,一個港口,無論如何。雖然你不想demonitor/1關閉監控端口的整個過程,但你應該使用參考。

1

只要記住PID就好了,如果你只是有一個小項目而且只有想監視一些進程。但我會建議使用參考,因爲項目增長迅速,您可能不僅需要監視過程。 Elixir在:erlang.monitor/2下使用,它還允許您在Erlang單調時間和Erlang系統時間之間監視portstime_offset。這可以在Docs here中找到。「參考」更通用,通常是更好地使用「參考」的實踐。

這裏一個小例子,我想說的:

iex(1)> :erlang.monitor(:time_offset, :clock_service) 
#Reference<0.0.3.100> 

iex(2)> :erlang.monitor(:process ,self()) 
#Reference<0.0.3.113> 
相關問題