Python多处理内存使用

Python多处理内存使用,python,linux,memory-management,multiprocessing,Python,Linux,Memory Management,Multiprocessing,我写了一个程序,可以总结如下: 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):

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

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()
仅使用这些作为参数的值(这意味着它不引用
数据

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

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

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


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

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

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


您可以通过在加载大量数据之前调用
多处理.Process
来避免这种情况。那么,当您将数据加载到父进程中时,额外的内存分配将不会反映在子进程中。

比我快,做得好。Linux是COW,因此当父进程写入数据时,数据将被复制。如果父进程只读取数据,那么将只有一个数据实例,但top(我几乎可以肯定)将显示属于这两个进程的数据。meminfo应该提供更准确的内存使用数据。我认为现在最常见的操作系统是COW(我只是想尽量做到通用)。很好的特性,但在解释基于进程的内存报告工具(即top、ps等)的输出时,常常会引起混淆meminfo将正确报告,Solaris上的
pmap
也将正确报告;但是不知道Windows:)还要注意,每个Python对象都包含一个引用计数,每当访问该对象时,该计数都会被修改。因此,仅仅读取一个数据结构就可能导致COW复制.Ty作为答案。在加载数据之前调用
multiprocessing.Process
,似乎解决了这个问题。我还将研究
meminfo
。@isedev甚至对表达式求值都会涉及临时引用。您能否重新构造代码以使用迭代器,而不是加载所有loadHugeData?如果它看起来是load/process/enqueue/dequeue/write,那么您可能会这样做。不幸的是,“hugeData”是一个以制表符分隔的txt文件,基本上包含一个稀疏数组。我需要在处理过程中根据行号“随机访问”这些数据。因此,将其加载到内存中(使用稀疏阵列特定优化)会使处理速度大大加快。建议使用类似“的方式进行流程集成”可能会大大超过工程设计,但了解它是否有帮助/可扩展/性能会很有趣。和往常一样,别人的问题总是更有趣。