2

这个问题不需要USB知识,只是将其描述为使示例更加具体。

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

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

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

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

我计划supervisor:which_children/1在每次扫描之前调用以找出哪些设备存在但没有运行子进程。

为了找出哪些地址有孩子在运行,我计划为包含地址的 childspec 创建 Id 原子(只有几个地址可能),例如, adr_12如果孩子处理 address 12

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

case supervisor:start_child(my_sup, Spec) of
    {error, already_present} ->
        supervisor:restart_child(my_sup, Spec);
    Any -> Any
end

然后是我不知道是否supervisor:which_children/1也返回已经终止的孩子的问题。

因此,最好在子节点暂时终止后将其删除。

不知何故,这一切对我来说都是不雅的,所以我问自己(和你):

我怎样才能最优雅地解决这个问题?

在这种情况下完全不使用主管会更好吗?

4

2 回答 2

2

我的直觉/膝跳反应是:“你需要为他们使用 simple_one_for_one”主管,所以当它停止时,他们的规范会被删除。如果您需要能够获取特定的通信过程,我会为此使用gproc应用程序(或 ETS 表)。

于 2011-03-12T23:57:36.500 回答
1

在我看来,您想要动态添加到主管的孩子彼此非常相似。也许您需要一个简单的一对一主管。这些主管是“one_for_one 主管的简化版本,其中所有子进程都是同一进程的动态添加实例。”。每个孩子都有相同的孩子规格,因此您在调用supervisor:add_child/2.

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

于 2011-03-12T23:58:09.253 回答