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

标签 erlang erlang-otp

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

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

有人能看出这个问题吗?还有其他更“正确”的方法吗?

最佳答案

一个问题是您有 ChildPid 并且 child 现在可能已经死了。因此,通过 cast 向其发送消息将意味着消息丢失。通过调用,您将因{'EXIT', noproc}而崩溃,除非您从调用中捕获它。您的解决方案必须考虑到 Pid 可能在您发送消息后就早已消失。通常是忽略消息丢失,让自己崩溃,或者解决问题然后继续。

有几个选项。这是一个松散的列表:

  • 照你做的做。让 child 自己登记。
  • 让逻辑模块在子模块上有一个监视器。这样你就知道它是否死了。
  • 使用Erlang解决方案 gproc模块:https://github.com/esl/gproc它为您提供了一个简洁的 ETS 表界面,用于跟踪信息。请注意,如果进程刚刚重新启动,您可以在 gproc 中查找 pid,并等待它的到来。
  • 使用 supervisor:which_children 查找相关子项。
  • 将您自己的 ETS 表作为 gproc 的变体进行滚动
  • 本地名称必须是原子,但全局注册名称可以是任何术语(它们内部存储在 ETS 表中,看起来有点像 gproc,请参阅 kernel/stdlib 中的 >global_name_server)。使用全局结构来跟踪有问题的 pid。

关于erlang - 在启动 start_child 调用的进程中注册子进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4348040/

相关文章:

erlang - simple_one_for_one只有在指定SHUTDOWN策略为brutal_kill时才可以终止?

mongodb - E11000 重复键错误索引 : MongoDb unusual error

web-services - Elixir - Simple Plug 示例在每次请求时两次调用调用方法

erlang - 我如何知道 Elixir 服务器上的可用内存量?

erlang - 解析 torrent 文件 - 哈希信息。 (二郎)

erlang - Erlang 消息队列是否跨进程持久化?

erlang - 为 Erlang 主管生临时 child 有什么意义?

erlang - 如何找到 OTP 流程的主管?

erlang - 为什么erlang :foo() compile?

javascript - 跨平台 AES 256 GCM Javascript 和 Elixir