在启动start_child调用的进程中注册子进程

JoG*_*oGr 5 erlang erlang-otp

我有一个逻辑模块,告诉主管启动子进程.我需要将这些儿童的pid存储在逻辑模块状态中.但是如果主管重新启动它,我还需要更新childs pid.

所以我不能使用start_child调用中的返回值pid,因为这只会在第一次启动时给出pid,而不是重启.现在我通过子inits函数在子逻辑模块中调用子进程调用寄存器函数(用新pid更新状态).这样,只要重新启动进程,逻辑模块就可以在其状态下更新pid.逻辑模块是gen_server,当我注册子进程时,我正在进行强制转换.

任何人都可以看到这个问题,还有其他更"正确"的方式吗?

I G*_*ERS 6

一个问题是,你ChildPid现在已经死了,孩子可能已经死了.因此通过a发送消息cast意味着消息丢失.通过一个call你将崩溃自己,{'EXIT', noproc}除非你把它赶出去call.您的解决方案必须考虑到Pid您发送消息的那一刻可能已经很久了.通常通过忽略消息丢失,崩溃自己,或通过纠正问题然后继续.

有几种选择.这是一个松散的清单:

  • 像你一样做.让孩子自己注册.
  • 让逻辑模块有一个monitor孩子.这样你知道它是否会死亡.
  • 使用Erlang Solutions gproc模块:https://github.com/esl/gproc,它为您提供了一个整洁的ETS表接口,可以跟踪信息.请注意,如果进程刚刚重新启动,您可以在gproc中查找pid并等待其到达.
  • 使用supervisor:which_children找到相关的孩子.
  • 滚动您自己的ETS表作为变体 gproc
  • 地方名必须是原子,但全球范围内注册的名称可以是任何条款(它们在内部存储在ETS表看有点像GPROC的,看到global_name_serverkernel/stdlib).使用全局结构来跟踪有问题的pids.