在erlang OTP中重新启动子级时,如何向主管提供额外信息?
假设我有一个主管在erlang OTP中重新启动子级时,如何向主管提供额外信息?,erlang,Erlang,假设我有一个主管sup管理一些工人,当工人开始工作时,它会用一些名字注册自己,比如worker\u 1,worker\u 2,等等。。当worker\N崩溃并通过sup重新启动时,如何将新创建的进程注册为worker\N,即,如何让worker的名称在重新启动后仍然有效 没有给出答案,因为我只需要名称,可能有一个解决方案。当工作进程启动时,您可以让它在init中调用register(name,self())并将name作为参数传递给它。这在整个节点上是全局的,所以注册过程是什么并不重要 但是 看
sup
管理一些工人,当工人开始工作时,它会用一些名字注册自己,比如worker\u 1
,worker\u 2
,等等。。当worker\N
崩溃并通过sup
重新启动时,如何将新创建的进程注册为worker\N
,即,如何让worker的名称在重新启动后仍然有效
没有给出答案,因为我只需要名称,可能有一个解决方案。当工作进程启动时,您可以让它在
init
中调用register(name,self())
并将name
作为参数传递给它。这在整个节点上是全局的,所以注册过程是什么并不重要
但是
看起来您是在动态创建原子,因为您希望在任何地方都使用已注册的进程。这是一个非常常见的错误——但还是有希望的
< >不要动态地创建原子来命名每个存在的童工,首先考虑一些事情:
- 你不需要所有的名字。工人的工作有限 描述(如果他们没有你有更大的问题),他们是 几乎总是与他们的资源、调用者或产卵者联系在一起, 谁已经认识他们了
- 您确实需要命名它们(但实际上,您可能不需要),因为它们
表示大型系统的具体元素,例如
游戏、聊天频道、跟踪受害者的推特订阅等。
通过保留
其中[{Key,Value}]
。这可以让您通过以下方式了解更多有关流程的信息: 查看其名称,并保持系统的全局空间不受影响 私人工人碎屑[{AnyTerm,Pid}]
如果你真的需要他们命名(发生),考虑使用<代码> Global 模块(它可以让你说出任何你想要的术语,所有的名字都可以在所有节点上使用——魔术!),在“代码> PG2< /Cult>模块中的“进程组”,或者(一个专门为处理这个问题而编写的库,还允许您使用任何想要命名进程的术语)
个人备忘 如果你发现自己处于一个生成动态原子似乎是个好主意的情况下(无论出于何种原因)无论你在做什么,你都应该停下来,认真思考你在做什么。这是因为产生原子强烈地表明你做错了。试着去发现你为什么要如此努力地与系统抗争——Erlang不应该以这种方式工作无论我在自己的代码中遇到过什么情况,还是在其他人的工作中看到过什么情况,这类事情都表明存在一种更干净、更环保的做事方式,如果我发现了这种方式,而不是在我正在处理的复杂逻辑中添加更多的层,一切就会变得更容易。好消息是总结Erlang习惯用法很快,而且很难忘记,因为回顾起来它们通常很有意义(几乎总是你发现自己在发现公认的解决方案之前就在重新发明轮子——最后会有一种“啊,伟大的人想法相似”的感觉).这是我迄今为止读到的关于stackoverflow的最好答案。感谢这些详细信息。我使用坐标作为名称,每个工人都做与该坐标相关的工作,然后通过
(x,y,z)!some_msg
,这就是为什么我要命名我的工人。这可以描述为“1-worker-1-coordinate”,如果我不说出它们的名字,那么它应该是一个“1-worker-many-coordinates”,对吗?在后一种情况下,它的常见模式是什么,我应该写一个调度器来告诉工人它应该处理哪条消息吗?我在写的一个教学项目中有一个相同的情况(我将一个项目从幼稚的非OTP发展为生产OTP风格)最初,我在“父级”中保留一个注册表(它是一个主管,但不是一个合适的)并响应{From,Ref,{get_pid,LocID}}
LocID
可以是任何东西,在这种情况下它是{X,Y,Z}
,但这是偶然的。稍后我将使用global
()和global:send(LocID,Msg)
代替LocPid!Msg
,稍后我将演示pg2和gproc。@另外,请注意,随着时间的推移,“裸体”发送形式为Destination!Message
的调用开始消失,并被包装在模块接口API后面。在项目的一开始,这可能会很麻烦,但一旦您确定了要做什么,将消息调用移到模块API后面可能会是一个真正的救命稻草——mo之间的状态数据访问也是如此dules(不要盲目地在标题中包含记录定义!)。下面是一个“位置管理器”的(非常非OTP)示例:@NotanID另外,不要将那里的代码视为canon。它被有意地编写为不规则的(但没有错)随着时间的推移,代码库将变得更加Erlangy——这就是演示的全部要点。gproc基本上提供了这个{K,V}为您键入Pid目录服务,预打包使用。非常酷。无论如何,手工编写一个目录服务是探索这个想法的好方法,并将使有关global、pg2和gproc的其他内容在以后对您有明显的意义。哦,伙计,这正是我需要的。