多处理全局变量内存复制

时间:2016-10-24 15:14:53

标签: python memory multiprocessing

我正在运行一个程序,它首先将20 GB数据加载到内存中。然后我将执行N(> 1000)个独立任务,其中每个任务可以使用(只读)20 GB数据的一部分。我现在正试图通过多处理来完成这些任务。但是,如this answer所述,将为每个进程复制整个全局变量。在我的情况下,我没有足够的内存来执行超过4个任务,因为我的内存只有96 GB。我想知道是否有任何这种问题的解决方案,以便我可以充分利用我的所有内核而不会消耗太多内存。

1 个答案:

答案 0 :(得分:4)

在linux中,分叉进程具有父地址空间的写时复制视图。 forking是轻量级的,并且相同的程序在父级和子级中运行,除了子级采用不同的执行路径。作为一个小例子,

import os
var = "unchanged"
pid = os.fork()
if pid:
    print('parent:', os.getpid(), var)
    os.waitpid(pid, 0)
else:
    print('child:', os.getpid(), var)
    var = "changed"

# show parent and child views
print(os.getpid(), var)

结果

parent: 22642 unchanged
child: 22643 unchanged
22643 changed
22642 unchanged

将此应用于多处理,在此示例中,我将数据加载到全局变量中。由于python会发送到进程池的数据,因此我确保它会像索引一样腌制一些小东西并让工作者自己获取全局数据。

import multiprocessing as mp
import os

my_big_data = "well, bigger than this"

def worker(index):
    """get char in big data"""
    return my_big_data[index]

if __name__ == "__main__":
    pool = mp.Pool(os.cpu_count())
    for c in pool.imap_unordered(worker, range(len(my_big_data)), chunksize=1):
        print(c)

Windows没有用于运行程序的fork-and-exec模型。它必须启动python解释器的新实例并将所有相关数据克隆到子节点。这是一个沉重的举动!