gpt4 book ai didi

Python多处理内存使用

转载 作者:IT王子 更新时间:2023-10-29 00:04:01 26 4
gpt4 key购买 nike

我写了一个程序,可以总结如下:

def loadHugeData():
#load it
return data

def processHugeData(data, res_queue):
for item in data:
#process it
res_queue.put(result)
res_queue.put("END")

def writeOutput(outFile, res_queue):
with open(outFile, 'w') as f
res=res_queue.get()
while res!='END':
f.write(res)
res=res_queue.get()

res_queue = multiprocessing.Queue()

if __name__ == '__main__':
data=loadHugeData()
p = multiprocessing.Process(target=writeOutput, args=(outFile, res_queue))
p.start()
processHugeData(data, res_queue)
p.join()

真正的代码(尤其是writeOutput())要复杂得多。 writeOutput() 仅使用它作为参数的这些值(意味着它不引用 data)

基本上,它将一个巨大的数据集加载到内存中并对其进行处理。输出的写入被委托(delegate)给一个子进程(它实际上写入多个文件,这需要很多时间)。因此,每次处理一个数据项时,它都会通过 res_queue 发送到子进程,然后根据需要将结果写入文件。

子进程不需要以任何方式访问、读取或修改loadHugeData()加载的数据。子进程只需要使用主进程通过 res_queue 发送给它的内容。这引出了我的问题。

在我看来,子进程获得了自己的庞大数据集副本(当使用 top 检查内存使用情况时)。这是真的?如果是这样,我该如何避免 id(本质上使用双内存)?

我正在使用 Python 2.6,程序在 linux 上运行。

最佳答案

multiprocessing 模块有效地基于创建当前进程副本的fork 系统调用。由于您在 fork(或创建 multiprocessing.Process)之前加载了大量数据,子进程继承了数据的副本。

但是,如果您运行的操作系统实现了 COW(写时复制),那么物理内存中实际上只有一份数据副本,除非您修改父进程或子进程中的数据(两者都 parent 和 child 将共享相同的物理内存页面,尽管在不同的虚拟地址空间中);即使这样,也只会为更改分配额外的内存(以 pagesize 为增量)。

您可以通过在加载大量数据之前调用 multiprocessing.Process 来避免这种情况。然后,当您在父进程中加载​​数据时,额外的内存分配将不会反射(reflect)在子进程中。

编辑:反射(reflect)了@Janne Karila 在答案中的评论,因为它是如此相关:“另请注意,每个 Python 对象都包含一个引用计数,只要访问该对象就会修改该引用计数。因此,仅读取数据结构可能会导致 COW复制。”

关于Python多处理内存使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14749897/

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