在主管树中终止子进程的正确方法是啥

Posted

技术标签:

【中文标题】在主管树中终止子进程的正确方法是啥【英文标题】:What is the correct way of terminating a child process in a supervisor tree在主管树中终止子进程的正确方法是什么 【发布时间】:2013-02-09 10:22:58 【问题描述】:

假设我有一个父级和一些子级的主管树。孩子们是短暂的。但被其他进程使用。父母负责将用户指向正确的孩子。

User  ---lookup(child)-->  Parent
User <----PidOfChild-----  Parent

User  --request(Resouce)--> Child
User <------respond------   Child

假设孩子在两个序列之间关闭,关闭孩子以避免用户端崩溃的正确方法是什么?

用户可以监控孩子,但这真的有帮助吗?因为用户在一个事务中完成所有这些操作?

【问题讨论】:

【参考方案1】:

在这种情况下,正确的解决方案是在用户端处理它:没有故障安全方法可以“关闭”子节点以使其响应用户。总会有比赛条件在某个地方搞砸。

如果您使用的是 gen_server:cast/call,您可以提供一个超时时间,用于在请求失败之前等待多长时间并适当地捕获它。如果使用原始接收块:

receive
    some_response -> ok, some_response
after
    5000 -> % do something.
end.

【讨论】:

我在想,我觉得有办法。首先在 User 和 parent 之间建立一个订阅模型,然后让 parent 负责关闭任何当前没有任何订阅的孩子,订阅模型可以通过简单的监视器来完成..【参考方案2】:

如果您正在考虑另一种方法来避免在用户端出现某些内容,如果您调用父级并立即调用子级,则可以将父级设置为消息代理。

User  ---request(Resouce)-->  Parent --request(Resouce)--> Child
User <---reponse------------  Parent <-response----------- Child

父级必须将请求强制转换给子级,以避免阻塞。这样,父母也可以跟踪孩子并相应地响应用户。如果孩子关闭,它可以相应地重新启动,或者如果没有活动的请求,它可以关闭孩子。父级不应该有任何处理,因为它可能成为这种方法的瓶颈。

【讨论】:

【参考方案3】:

如果您的请求是在子关闭之前构建的,您应该使用 receive ... after ... 或 gen_server:call 方案。 如果您的请求是在子关闭后构建的,也许您可​​以将请求挂起直到超时或子可用。

【讨论】:

以上是关于在主管树中终止子进程的正确方法是啥的主要内容,如果未能解决你的问题,请参考以下文章

如何检查子进程是不是正确终止? [复制]

正确关闭 Python 中的子进程 [重复]

如何从受监督的工作进程中触发 Elixir 主管树终止

在 C 中等待子进程终止的最佳实践

为啥子进程中的管道有时会中断,有时不会?

使用主管为每个节点启动 elixir 子进程