[英]Python multiprocessing memory usage
我写了一个程序,可以总结如下:
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
)
基本上它将一个巨大的数据集加载到内存中并对其进行处理。 输出的写入委托给一个子进程(它实际上写入多个文件,这需要很多时间)。 因此,每次处理一个数据项时,它都会通过 res_queue 发送到子进程,然后根据需要将结果写入文件。
子进程不需要以任何方式访问、读取或修改loadHugeData()
加载的数据。 子进程只需要使用主进程通过res_queue
发送的内容。 这将我引向我的问题和疑问。
在我看来,子进程获得了自己的庞大数据集的副本(使用top
检查内存使用情况时)。 这是真的? 如果是这样,那么我如何避免 id (本质上使用双内存)?
我正在使用 Python 2.6 并且程序在 linux 上运行。
multiprocessing
模块有效地基于创建当前进程副本的fork
系统调用。 由于您在fork
(或创建multiprocessing.Process
)之前加载大量数据,因此子进程继承了数据的副本。
但是,如果您运行的操作系统实现了 COW(写时复制),那么物理内存中实际上只会有一份数据副本,除非您在父进程或子进程(父进程和子进程)中修改数据将共享相同的物理内存页面,尽管在不同的虚拟地址空间中); 即便如此,额外的内存也只会分配给更改(以pagesize
增量)。
您可以通过在加载大量数据之前调用multiprocessing.Process
来避免这种情况。 那么当您在父进程中加载数据时,额外的内存分配将不会反映在子进程中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.