gpt4 book ai didi

python - python 子进程的垃圾收集

转载 作者:行者123 更新时间:2023-12-01 01:18:16 25 4
gpt4 key购买 nike

tl;dr:我的任务返回值很大,会消耗大量内存。我将它们提交给concurrent.futures.ProcessPoolExecutor。子进程会保留内存,直到收到新任务。如何强制子进程有效地进行垃圾回收?

示例

import concurrent.futures
import time

executor = concurrent.futures.ProcessPoolExecutor(max_workers=1)

def big_val():
return [{1:1} for i in range(1, 1000000)]

future = executor.submit(big_val)

# do something with future result

在上面的示例中,我在子进程中创建一个大对象,然后处理结果。从现在开始,我可以处理父进程中的内存,但由 ProcessPoolExecutor 创建的子进程将无限期地保留为我的任务分配的内存。

我尝试过的

老实说,我唯一能想到的就是提交一个虚拟任务:

def donothing():
pass

executor.submit(donothing)

这可行,但a)相当笨重,更重要的是b)不值得信赖,因为我无法保证将任务发送到哪个子进程,所以唯一万无一失的方法是发送洪水以确保子进程我想得到一份副本。

据我所知,一旦工作进程完成运行我的任务,它就没有理由保留结果。如果我的父进程将返回的 Future 分配给局部变量,那么任务完成后,返回值将被复制到父进程中的 Future 中,这意味着 worker 不再需要它。如果我的父进程没有这样做,那么返回值无论如何都会被有效地丢弃。

我是否误解了这里的某些内容,或者这只是子进程如何引用内存的一个不幸的怪癖?如果是这样,有更好的解决方法吗?

最佳答案

您的虚拟任务方法是在不进行大量代码重构的情况下完成此任务的唯一方法(以避免返回巨大的值)。

问题在于工作进程 binds the result to a local name r before sending it back to the parent ,并且仅在新任务出现时替换 r

您可以合理地在 the CPython bug tracker 上提出增强/错误请求让工作人员在调用 _sendback_result 后显式 del r ;它已经出于完全相同的原因对 call_item (打包的函数和发送给工作人员的参数)执行了此操作,以避免保留超出其有用窗口的资源,并且这样做是有意义的已经返回且不再相关的结果的事情。

关于python - python 子进程的垃圾收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54108434/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com