我正在使用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)
问题在于,所有子进程都需要相同的全局数据来处理该函数,因此加载该函数需要花费很长时间,这是在所有子进程之间共享此数据的最佳解决方案,因为该数据已经在其中加载父母?
答案 0 :(得分:1)
ms-windows上的多处理与类似UNIX的系统不同。
类似于UNIX的系统具有fork
系统调用,该系统调用将复制当前进程。在具有写时复制虚拟内存管理的现代系统中,这甚至不是很昂贵的操作。
这意味着父进程中的全局数据将与子进程共享,直到子进程写入该页面为止,在这种情况下将被复制。
问题是ms-windows没有fork
。它改为有CreateProcess
。因此在ms-windows上会发生这种情况:
父进程将启动一个全新的python解释器进程。子进程将仅继承运行进程对象run()方法所需的那些资源。特别是,父进程中不必要的文件描述符和句柄将不会被继承。与使用fork或forkserver相比,使用此方法启动进程相当慢。
因此,由于在函数中引用了全局数据,因此将对其进行加载。 但是每个子进程都将分别加载。
您可以尝试的是让您的进程使用mmap
和ACCESS_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))