![](/img/trans.png)
[英]Python 3.8 shared_memory resource_tracker producing unexpected warnings at application close
[英]In python 3.8 shared_memory the resource_tracker needs to be inherited by subprocesses, but how is that accomplished?
基于此错误报告中的讨论以及相关的 SO 问题:
在子进程中使用shared_memory
时, resource_tracker
需要从父进程继承。 如果不是,那么每个子进程都会错误地获得自己的resource_tracker
。
我没有在我的代码中的任何地方实例化
resource_tracker
。 继承resource_tracker
意味着什么? 在创建新的子进程之前,如何在主进程中实例化resource_tracker
,以便子进程继承resource_tracker
?
在子进程中使用 shared_memory 时,resource_tracker 需要从父进程继承。 如果不是,那么每个子进程都会错误地获得自己的 resource_tracker。
考虑到ResourceTracker
和SharedMemory
的当前实现,这种说法是有很大缺陷的。 前者实现为一个单独的 python 进程,该进程与启动它的进程(即创建共享 memory 对象的进程)通过 pipe 进行通信。 资源跟踪器具有 pipe 的读取端,而创建共享 memory 对象的进程获得它的写入端。 因此,每当启动进程创建SharedMemory
object 时,它都会通过 pipe 向资源跟踪器发送一条消息以register
创建的资源。 同样,如果需要移除资源,启动进程将再次使用 pipe 发送unregister
消息。 因此,子进程真正继承其父进程的资源跟踪器的唯一方法是,它使用 pipe 的写入端(它应该有权访问)直接向资源跟踪器发送消息。 然而,由于SharedMemory
的当前实现创建了一个资源跟踪器,即使一个进程只使用已经创建的共享 memory object,您的子进程将不得不与两个单独的资源跟踪器通信:一个由其父进程启动(通过同一管道),以及第一次实例化SharedMemory
object 时开始的那个。 有了这个,让我们来解决你的问题:
我没有在我的代码中的任何地方实例化 resource_tracker。 继承 resource_tracker 意味着什么?
首先,您不实例化资源跟踪器; 当您第一次实例化SharedMemory
object 时,会为您实例化一个。 目前,您是否生产或使用共享 memory object 并不重要。 始终为实例化共享 memory 对象的进程创建资源跟踪器。
其次,在当前的实现中,继承资源跟踪器确实不是一件事情。 同样,消费进程不应该担心共享 memory 对象的生命周期。 他们所要担心的是确保 object 确实存在。 他们可以通过处理FileNotFoundError
或OSError
异常来做到这一点。 如果SharedMemory
的当前实现没有问题,当使用资源完成消费进程时,他们需要做的就是调用SharedMemory.close
并继续执行其他操作。
在创建新的子进程之前,如何在主进程中实例化 resource_tracker,以便子进程继承 resource_tracker?
我认为这里的问题是你的设计被翻转了。 您应该让您的主进程创建共享 memory object 并让子进程使用它。 使用共享 memory 对象背后的想法是,您可以使用相同的 memory 块拥有多个单独的进程,这反过来会限制并行程序使用的资源量。 但是链接的 SO 帖子中的代码正在做相反的事情。 由于共享的 memory 对象是 kernel 持久资源,因此尽可能少地拥有它们是有意义的。 因此,如果您采用“一个生产者,多个消费者”设计,您可以让您的主进程创建共享的 memory object 及其相关的资源跟踪器,然后让子进程使用 ZCD69B4957F06CD818D7BF3D61980。 在这种情况下,您可以在子进程中完成一些工作,而不必担心与它们关联的资源跟踪器。 但只要确保子进程在父进程开始执行它之前不要取消链接共享的 memory object 。 更好的是,如果错误报告中的修复得到实施,使得消耗进程无需生成资源跟踪器,您可以确信您的主进程将是唯一取消链接共享 memory object 的实体。
总之,就当前实现而言,您的子进程不会继承其父进程的资源跟踪器。 如果这些子进程最终实际上创建了共享的 memory 对象,它们将获得自己的资源跟踪器。 但是,如果效率是目标,您可能希望您的主进程创建共享的 memory 对象,然后您的子进程将使用这些对象。 在这种情况下,您的主进程将通过其关联的资源跟踪器负责清理步骤。 而且,如果实施了修复,您始终可以安全地假设只有主进程将取消链接资源。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.