Python 共享只读数据是否复制到不同的进程以进行多处理?
我的代码看起来像这样:Python 共享只读数据是否复制到不同的进程以进行多处理?,python,numpy,multiprocessing,Python,Numpy,Multiprocessing,我的代码看起来像这样: glbl_array = # a 3 Gb array def my_func( args, def_param = glbl_array): #do stuff on args and def_param if __name__ == '__main__': pool = Pool(processes=4) pool.map(my_func, range(1000)) 是否有办法确保(或鼓励)不同进程不会获得glbl_数组的副本,而是共享它。如果无
glbl_array = # a 3 Gb array
def my_func( args, def_param = glbl_array):
#do stuff on args and def_param
if __name__ == '__main__':
pool = Pool(processes=4)
pool.map(my_func, range(1000))
是否有办法确保(或鼓励)不同进程不会获得glbl_数组的副本,而是共享它。如果无法停止复制,我将使用memmapped数组,但我的访问模式不是很规则,因此我预计memmapped数组的速度会较慢。这似乎是第一件要尝试的事情。这是在Linux上实现的。我只是想从Stackoverflow那里得到一些建议,不想惹恼系统管理员。如果第二个参数是一个真正的不可变对象,如
glbl\u array.tostring()
您可以很容易地将多处理
中的共享内存与Numpy一起使用,您认为这会有帮助吗:
import multiprocessing
import ctypes
import numpy as np
shared_array_base = multiprocessing.Array(ctypes.c_double, 10*10)
shared_array = np.ctypeslib.as_array(shared_array_base.get_obj())
shared_array = shared_array.reshape(10, 10)
#-- edited 2015-05-01: the assert check below checks the wrong thing
# with recent versions of Numpy/multiprocessing. That no copy is made
# is indicated by the fact that the program prints the output shown below.
## No copy was made
##assert shared_array.base.base is shared_array_base.get_obj()
# Parallel processing
def my_func(i, def_param=shared_array):
shared_array[i,:] = i
if __name__ == '__main__':
pool = multiprocessing.Pool(processes=4)
pool.map(my_func, range(10))
print shared_array
哪张照片
[[0.0.0.0.0.0.0.0.0.0.0]
[ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
[ 2. 2. 2. 2. 2. 2. 2. 2. 2. 2.]
[ 3. 3. 3. 3. 3. 3. 3. 3. 3. 3.]
[ 4. 4. 4. 4. 4. 4. 4. 4. 4. 4.]
[ 5. 5. 5. 5. 5. 5. 5. 5. 5. 5.]
[ 6. 6. 6. 6. 6. 6. 6. 6. 6. 6.]
[ 7. 7. 7. 7. 7. 7. 7. 7. 7. 7.]
[ 8. 8. 8. 8. 8. 8. 8. 8. 8. 8.]
[9.9.9.9.9.9.9.9.9.9.9.]
但是,Linux在
fork()
上有写时复制语义,因此即使不使用多处理.Array
,数据也不会被复制,除非它被写入。对于那些使用Windows的用户,Windows不支持fork()
(除非使用CygWin),pv的答案不起作用。全局变量不提供给子进程
相反,您必须在池的初始化过程中传递共享内存,如下所示:
#! /usr/bin/python
import time
from multiprocessing import Process, Queue, Array
def f(q,a):
m = q.get()
print m
print a[0], a[1], a[2]
m = q.get()
print m
print a[0], a[1], a[2]
if __name__ == '__main__':
a = Array('B', (1, 2, 3), lock=False)
q = Queue()
p = Process(target=f, args=(q,a))
p.start()
q.put([1, 2, 3])
time.sleep(1)
a[0:3] = (4, 5, 6)
q.put([4, 5, 6])
p.join()
(这不是numpy,也不是很好的代码,但它说明了这一点;-)以下代码在Win7和Mac上工作(可能在linux上,但未经测试)
如果您正在寻找一种在Windows上高效运行的选项,并且适用于不规则访问模式、分支和其他可能需要基于共享内存矩阵和处理本地数据的组合分析不同矩阵的场景,软件包中的mathDict工具包就是为了处理这种情况而设计的。我认为不同的进程不能共享内存variables@Andrey当前位置然后你今天学到了一些东西:)唯一的限制是。多处理是指在调用pool.map
之前定义共享数组\u basefork()
和multiprocessing.Pool
不会重新导入模块,因此您需要注意的唯一一件事是my_func()
中的内存分配。请注意,在Python fork()上实际上意味着访问时复制(因为仅访问对象就会更改其引用计数)。该副本将仅复制refcount整数所在的内存页。因此,Numpy数组中的数据不会被复制。明白了。您应该使用np.frombuffer(shared\u array\u base.get\u obj())而不是np.ctypeslib.as\u array我猜这在Windows上不起作用,因为没有使父变量对子变量可见的fork()
。对吗?如果是这样,您将如何将共享阵列传递给该操作系统上的池工作者?
#! /usr/bin/python
import time
from multiprocessing import Process, Queue, Array
def f(q,a):
m = q.get()
print m
print a[0], a[1], a[2]
m = q.get()
print m
print a[0], a[1], a[2]
if __name__ == '__main__':
a = Array('B', (1, 2, 3), lock=False)
q = Queue()
p = Process(target=f, args=(q,a))
p.start()
q.put([1, 2, 3])
time.sleep(1)
a[0:3] = (4, 5, 6)
q.put([4, 5, 6])
p.join()
import multiprocessing
import ctypes
import numpy as np
#-- edited 2015-05-01: the assert check below checks the wrong thing
# with recent versions of Numpy/multiprocessing. That no copy is made
# is indicated by the fact that the program prints the output shown below.
## No copy was made
##assert shared_array.base.base is shared_array_base.get_obj()
shared_array = None
def init(shared_array_base):
global shared_array
shared_array = np.ctypeslib.as_array(shared_array_base.get_obj())
shared_array = shared_array.reshape(10, 10)
# Parallel processing
def my_func(i):
shared_array[i, :] = i
if __name__ == '__main__':
shared_array_base = multiprocessing.Array(ctypes.c_double, 10*10)
pool = multiprocessing.Pool(processes=4, initializer=init, initargs=(shared_array_base,))
pool.map(my_func, range(10))
shared_array = np.ctypeslib.as_array(shared_array_base.get_obj())
shared_array = shared_array.reshape(10, 10)
print shared_array