Elixir的Mix and OTP Guide Chapter GenServer解释了如何使用GenServer
实现代理服务器控制代理。
每个代理的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>
)。 :DOWN
捕获的handle_info/2
消息提供PID和参考。
因为我们始终都知道这两个值:使用引用作为使用refs
中的PID的关键有什么好处,如果有的话?
答案 0 :(得分:3)
这是一致性的问题。虽然您只监控过程,但没有区别。但是基础:erlang.monitor/2
可以监控不仅的进程:有端口等,基本上没有PID
。
来自doc:
•
Object
被监控的实体,它触发了该事件。监控本地流程或端口时,
Object
将等于受监控的pid()
或port()
。在按名称监控流程或端口时,Object
的格式为{RegisteredName, Node}
,其中RegisteredName
是monitor/2
电话使用的名称,Node
是本地或远程节点名称(对于按名称监视的端口,Node
始终是本地节点名称)。
总结:Reference
是一个被监控的实体。它可能是一个过程,一个端口,等等。虽然您不希望demonitor/1
关闭监控端口的整个过程,但您应该使用引用。
答案 1 :(得分:2)
如果您只有一个小项目并且仅想要监控某些进程,那么只记住PID就可以了。但我建议使用Reference,因为Projects增长很快,您可能不仅要监视进程。 Elixir在:erlang.monitor/2
下方使用,它还允许您在Erlang单调时间和Erlang系统时间之间监视ports
和time_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>