Erlang 如何在动态管理器中自动删除终止子级的规范

Erlang 如何在动态管理器中自动删除终止子级的规范,erlang,otp,erlang-supervisor,Erlang,Otp,Erlang Supervisor,这个问题不需要了解USB,只需描述它,使示例更加具体 我正在尝试为USB总线上的特定设备实现一个动态监控器。 这些设备具有地址,并在系统生命周期内出现和消失 对于每个设备,我需要一个动态的孩子作为我的主管 这些子项是暂时的,所以一旦它们崩溃或终止,我们就不会重新启动它们(因为它们可能已经不在了) 我有一个进程,在特定时间扫描USB端口,并生成一个列表,列出我要处理的USB设备的所有地址 我计划在每次扫描之前致电主管:which_children/1,以确定哪些设备存在但没有运行子进程 为了找出哪

这个问题不需要了解USB,只需描述它,使示例更加具体

我正在尝试为USB总线上的特定设备实现一个动态监控器。 这些设备具有地址,并在系统生命周期内出现和消失

对于每个设备,我需要一个动态的孩子作为我的主管

这些子项是暂时的,所以一旦它们崩溃或终止,我们就不会重新启动它们(因为它们可能已经不在了)

我有一个进程,在特定时间扫描USB端口,并生成一个列表,列出我要处理的USB设备的所有地址

我计划在每次扫描之前致电
主管:which_children/1
,以确定哪些设备存在但没有运行子进程

为了找出哪些地址有子级运行,我计划为包含地址的childspec创建Id原子(可能只有少数地址),例如,如果子级处理地址
12
,则为其创建Id原子

当我尝试启动/重新启动丢失的子级时,我遇到了一个有点糟糕的情况,即当临时子级终止或崩溃时,子级规范不会自动删除(至少我认为是这样)。所以我需要这样的代码:

case supervisor:start_child(my_sup, Spec) of
    {error, already_present} ->
        supervisor:restart_child(my_sup, Spec);
    Any -> Any
end
还有一个问题,我不知道supervisor:which_children/1是否也返回已经终止的子项

因此,最好在孩子短暂终止后删除他们

不知何故,我觉得这一切都不雅观,所以我问自己(和你):

我如何才能最优雅地解决这个问题


在这种情况下,根本不使用主管是否更好?

我的直觉/下意识反应是:“你需要为他们使用一个简单的“一对一”主管,这样他们的规范在停止时就会被删除。如果您需要能够获取特定的通信过程,我会使用gproc应用程序(或ETS表)。

我觉得您要动态添加到主管中的孩子彼此非常相似。也许你需要一个主管。这些监控程序是“一对一监控程序的简化版本,其中所有子进程都是动态添加到同一进程的实例中。”。每个子级都有相同的子级规格,因此在调用
主管:add_child/2
时不需要指定它


此外,请注意,上述动态创建原子(例如,
adr_12
)的想法可能是危险的。原子在Erlang系统中受到限制(默认为1000000)。有关详细信息,请参阅文档。

USB总线上只有127个可能的地址,只使用了较低的地址->因此创建atom肯定不是问题。我只是觉得提到这个问题很有用-有人可能会看到这个问题,并认为对更多的孩子使用相同的方法-请参阅我对@IGCA的回答的评论简单的一对一的问题是,不容易找到缺少进程的地址。我必须实现一个单独的地址注册表来监控进程。那么简单的一对一管理器有什么作用呢?gproc听起来确实很吸引人。简单的一对一管理器是用来连接进程的,所以如果其他进程死亡,你可以优雅地关闭USB链接。这是清理用的,没别的。我明白了。然而,这并不是我所关心的:对于一个孩子处理的每个USB设备,都会启动一系列完整的链接进程。如果这里出现严重问题,那么不管怎样,孩子都会被终止并重新启动。此外,还插入了新设备,有时设备会消失并重新出现(相当快)。我正在试验一个普通的一对一的管理者,在扫描过程中添加了一个被删除的孩子(消失和再现通常在同一个地址,可以由管理者自动处理)。顺便说一句:这个地址不需要抓取一个通信过程,只需要启动正确的USB处理程序(地址是由操作系统动态提供的,与任何有用的东西都没有关系)。我已经有了一个单独的注册表,它由我与设备交谈后的设备序列号驱动。