如何自动删除动态主管中已终止子女的规格
没有这个问题所需的USB知识,只是描述它是为了让这个例子更具针对性。
我正试图为USB总线上的特定设备实现动态管理器。 这些设备具有地址并在系统的生命周期中出现并消失。
对于每台设备,我都需要一位充满活力的孩子为我的主管。
这些孩子是短暂的,所以一旦他们崩溃或终止,我们不会重新启动他们(因为他们可能已经消失了)。
我有一个在特定时间扫描USB端口的进程,并生成我想要处理的USB设备的所有地址列表。
我计划在每次扫描之前调用supervisor:which_children/1
以查明哪些设备存在但没有子进程正在运行。
为了找出哪些地址有小孩在运行,我计划为childspec创建包含地址的Id原子(只有几个可能的地址),例如,如果孩子处理地址12
, adr_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
也返回已经终止的孩子。
因此,如果孩子在短暂结束之后被删除,那么最好。
不知何故,所有这些对我来说都是不雅的,所以我问自己(和你):
我怎样才能最优雅地解决这个问题?
在这种情况下最好不要使用监督员?
我的直觉/膝盖混乱反应是:'你需要为他们使用一个simple_one_for_one'主管,所以他们的规格在停止时被移除。 如果您需要能够获取特定的通信流程,那么我会使用gproc应用程序(或ETS表格)。
这听起来像你想要动态添加到你的主管的孩子们彼此非常相似。 也许一个简单的一对一的主管是你需要的。 这些主管是“one_for_one主管的简化版本,其中所有子进程都是动态添加同一进程的实例。” 每个孩子都有相同的孩子规格,所以当你打电话给supervisor:add_child/2
时,你不需要指定它supervisor:add_child/2
。
另外,请注意,上述动态创建原子(例如adr_12
)的想法可能会很危险。 Erlang系统中的原子是有限的(默认为〜1000000)。 详情请参阅文档。
上一篇: How to atomatically delete specs of terminated children in a dynamic supervisor