具有大量共享数据的Python多重处理

时间:2018-12-18 11:26:48

标签: python windows parallel-processing multiprocessing

我正在使用python开发一个应用来使用mutliprocessing模块处理数据,该代码如下所示:

import multiprocessing

globalData = loadData() #very large data 

def f(v):
    global globalData
    return someOperation(globalData,v)

if __name__ == '__main__':
    pool = multiprocessing.Pool()
    arr = loadArray() #some big list
    res = pool.map(f,arr)

问题在于,所有子进程都需要相同的全局数据来处理该函数,因此加载该函数需要花费很长时间,这是在所有子进程之间共享此数据的最佳解决方案,因为该数据已经在其中加载父母?

2 个答案:

答案 0 :(得分:1)

ms-windows上的多处理与类似UNIX的系统不同。

类似于UNIX的系统具有fork系统调用,该系统调用将复制当前进程。在具有写时复制虚拟内存管理的现代系统中,这甚至不是很昂贵的操作。

这意味着父进程中的全局数据将与子进程共享,直到子进程写入该页面为止,在这种情况下将被复制。

问题是ms-windows没有fork。它改为有CreateProcess。因此在ms-windows上会发生这种情况:

  

父进程将启动一个全新的python解释器进程。子进程将仅继承运行进程对象run()方法所需的那些资源。特别是,父进程中不必要的文件描述符和句柄将不会被继承。与使用fork或forkserver相比,使用此方法启动进程相当慢。

因此,由于在函数中引用了全局数据,因此将对其进行加载。 但是每个子进程都将分别加载

您可以尝试的是让您的进程使用mmapACCESS_READ来加载数据。我期望,ms-windows内存子系统足够聪明,以防万一同一文件被多个进程加载,仅加载一次数据。

答案 1 :(得分:0)

我也是python的新手,但是,如果我确实理解了您的问题,那非常简单:在以下脚本中,我们使用5个工人获得前10000个数字的平方。

import multiprocessing

globalData = range(10000) #very large data 

def f(x):
  return x*x

if __name__ == '__main__':
    pool = multiprocessing.Pool(5)
    print(pool.map(f,globalData))