如何在动态管理程序中自动删除已终止子项的规范

发布于 2024-10-21 08:04:51 字数 905 浏览 4 评论 0原文

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

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

对于每台设备,我都需要为我的主管提供一个动态的子设备。

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

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

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

为了找出哪些地址有子进程在运行,我计划为包含地址的子规范创建 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 是否也返回已经终止的子项。

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

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

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

在这种情况下,最好不要使用主管吗?

No knowledge of USB needed for this question, just described it as it is to make the example more conrete.

I'm trying to implement a dynamic supervisor for specific devices on a USB bus.
These devices have addresses and appear and disappear during the lifetime of the system.

For each device I need a dynamic child for my supervisor.

These children are transient, so once they crash or terminate we don't restart them (because probably they are gone then).

I have a process that scans the USB port at certain times and produces a list of all addresses of the USB devices I want to handle.

I plan to call supervisor:which_children/1 before each scan to find out which devices are present but have no child process running.

In order to find out which addresses have children running I plan to create Id atoms for the childspec that contain the addresses (there are only a few addresses possible), e.g. adr_12 if the child handles address 12.

When I try to start/restart missing children I have the somewhat ugly situation that the child specs are not automatically deleted when the transient child terminates or crashes (at least I think that it is so). So I would need code like this:

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

Then there is the problem that I don't know if supervisor:which_children/1 also returns already terminated children.

So it would be best if children would be deleted after they transiently terminate.

Somehow all this feels inelegant to me so I'm asking myself (and you):

How can I resolve this most elegantly?

Is it better not to use a supervisor at all in this situation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

花开浅夏 2024-10-28 08:04:51

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

My gut feeling/knee jerk reaction is: 'You need to use a simple_one_for_one' supervisor for them, so their spec gets removed when it stops. If you need to be able to grab a specific process for communication, I would use the gproc application for that (or an ETS table).

假装爱人 2024-10-28 08:04:51

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

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

It sounds to me like the children you want to dynamically add to your supervisor are very similar each other. Maybe a simple-one-for-one supervisor is what you need. These supervisors are "a simplified version of the one_for_one supervisor, where all child processes are dynamically added instances of the same process.". Every child will have the same child specs, so you don't need to specify it when you call the supervisor:add_child/2.

Also, mind that the above idea of creating an atom (e.g. adr_12) dynamically could be dangerous. Atoms are limited in an Erlang system (by default ~1000000). See the documentation for details.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文