对于这个问题不需要USB知识,只是将其描述为使示例更加清晰。
我正在尝试为USB总线上的特定设备实现动态管理程序。 这些设备具有地址,并在系统的生命周期内出现和消失。
对于每个设备,我需要为我的主管提供一个动态的孩子。
这些孩子是短暂的,所以一旦他们崩溃或终止,我们就不会重新启动它们(因为可能它们已经消失了)。
我有一个过程会在特定时间扫描USB端口,并生成一个我想要处理的USB设备的所有地址列表。
我打算在每次扫描之前调用supervisor:which_children/1
以找出存在哪些设备但没有运行子进程。
为了找出哪些地址有子运行我计划为包含地址的childspec创建Id原子(只有几个地址可能),例如如果孩子处理地址adr_12
,则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
是否还返回已经终止的孩子。
因此,如果孩子们在短暂终止后会被删除,那将是最好的。
不知何故,这一切对我来说都不优雅,所以我问自己(和你):
我怎样才能最优雅地解决这个问题?
在这种情况下,最好不要使用主管吗?
答案 0 :(得分:2)
我的直觉/膝跳反应是:'你需要为他们使用一个simple_one_for_one'主管,所以他们的规格在停止时会被移除。如果您需要能够获取特定的通信过程,我会使用 gproc 应用程序(或ETS表)。
答案 1 :(得分:1)
听起来我想要动态添加到主管的孩子彼此非常相似。也许你需要simple-one-for-one主管。这些主管是“one_for_one主管的简化版本,其中所有子进程都是动态添加同一进程的实例。”每个孩子都有相同的子规格,因此您在拨打supervisor:add_child/2
时无需指定。
另外,请注意上述动态创建原子(例如adr_12
)的想法可能很危险。 Erlang系统中的原子是有限的(默认为~1000000)。有关详细信息,请参阅文档。