Python:如何在多进程池中使用Value和Array

13

对于使用Processmultiprocessing,我可以通过设置args参数来使用Value, Array.

但是,在使用Poolmultiprocessing中,我该如何使用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[:])

以下代码片段中,我尝试使用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
1个回答

17

我一直不知道这个问题的原因,但是multiprocessingmp)在对大多数Pool方法传递的函数使用不同的pickler/unpickler机制。由此导致像mp.Valuemp.Arraymp.Lock等创建的对象不能作为这些方法的参数传递,尽管它们可以作为mp.Process的参数以及mp.Pool()的可选initializer函数的参数传递。由于后者,以下代码能够运行:

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[:])

并且打印

[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]

这是我所知道的跨平台解决方法。

在类 Unix 平台上(使用 fork() 生成新进程的平台),您可以在进行 mp.Pool() 操作之前,将您的 mp.Arraymp.Value 等对象作为模块全局变量创建。由 fork() 生成的进程会继承执行 mp.Pool() 时模块全局地址空间中的内容。

但是,在不支持 fork() 的平台(如 Windows)上完全行不通。


如果您的原始问题已经得到回答,您应该接受这个答案,并针对新问题开启新的议题。否则,帖子将变成一个无法理解的乱糟糟的堆积,充斥着无休止的不相关评论。 - Tim Peters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接