Mer*_*lin 6 python arrays pool multiprocessing
对于multiprocessing有Process,我可以使用Value, Array设置argsPARAM.
随着multiprocessing用Pool,怎么用Value, Array.没有什么在如何做到这一点的文档.
from multiprocessing import Process, Value, Array
def f(n, a):
n.value = 3.1415927
for i in range(len(a)):
a[i] = -a[i]
if __name__ == '__main__':
num = Value('d', 0.0)
arr = Array('i', range(10))
p = Process(target=f, args=(num, arr))
p.start()
p.join()
print(num.value)
print(arr[:])
Run Code Online (Sandbox Code Playgroud)
我想Value, Array在下面的代码片段中使用.
import multiprocessing
def do_calc(data):
# access num or
# work to update arr
newdata =data * 2
return newdata
def start_process():
print 'Starting', multiprocessing.current_process().name
if __name__ == '__main__':
num = Value('d', 0.0)
arr = Array('i', range(10))
inputs = list(range(10))
print 'Input :', inputs
pool_size = multiprocessing.cpu_count() * 2
pool = multiprocessing.Pool(processes=pool_size,initializer=start_process, )
pool_outputs = pool.map(do_calc, inputs)
pool.close() # no more tasks
pool.join() # wrap up current tasks
print 'Pool :', pool_outputs
Run Code Online (Sandbox Code Playgroud)
我从来不知道"原因",但是multiprocessing(mp)对传递给大多数Pool方法的函数使用不同的pickler/unpickler机制.它是由对象之类的东西产生的后果mp.Value,mp.Array,mp.Lock,...,不能作为参数传递给这些方法过去了,虽然它们可以作为参数传递mp.Process ,并以可选initializer的功能mp.Pool().由于后者,这有效:
import multiprocessing as mp
def init(aa, vv):
global a, v
a = aa
v = vv
def worker(i):
a[i] = v.value * i
if __name__ == "__main__":
N = 10
a = mp.Array('i', [0]*N)
v = mp.Value('i', 3)
p = mp.Pool(initializer=init, initargs=(a, v))
p.map(worker, range(N))
print(a[:])
Run Code Online (Sandbox Code Playgroud)
那打印
[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
Run Code Online (Sandbox Code Playgroud)
这是我所知道的跨平台工作的唯一方式.
在Linux-y平台上(mp通过创建新进程fork()),您可以在执行之前随时创建mp.Array和/ mp.Value(等)对象作为模块全局变量.通过继承当时模块全局地址空间中的任何内容创建的进程执行.mp.Pool()fork()mp.Pool()
但这在不支持的平台(读取"Windows")上根本不起作用fork().