python3多进程共享numpy的阵列(只读)(python3 multiprocess shar

2019-10-16 13:30发布

我不知道,如果这个称号是适合我的情况:我为什么要分享numpy的数组,这可能是我的情况下,潜在的解决方案的原因之一,但如果你有其他的解决方案,也将是不错。

我的任务:我需要实现一个迭代算法 ,而每个流程都需要有数据的副本(此数据为大, 只读和迭代算法中不会改变)。

我已经写了一些伪代码来证明我的想法:

import multiprocessing


def worker_func(data, args):
    # do sth...
    return res

def compute(data, process_num, niter):
    data
    result = []
    args = init()

    for iter in range(niter):
        args_chunk = split_args(args, process_num)
        pool = multiprocessing.Pool()
        for i in range(process_num):
            result.append(pool.apply_async(worker_func,(data, args_chunk[i])))
        pool.close()
        pool.join()
        # aggregate result and update args
        for res in result:
            args = update_args(res.get())

if __name__ == "__main__":
    compute(data, 4, 100)

问题是在每次迭代中,我必须将数据传递到子处理,这是非常耗时的。

我来了两个可能的解决方案:

  1. 进程间共享数据(这是ndarray),这是这个问题的标题。
  2. 保持子活着,像一个守护进程或东西...并等待来电。 通过这样做,我只需要在一开始传递数据。

那么,有没有什么办法可以共享过程中的只读numpy的阵列? 或者,如果你有一个很好的实施方案二,它也适用。

提前致谢。

Answer 1:

如果你绝对必须使用Python多,那么你可以使用Python多沿箭头血浆对象存储到存储在共享内存中的对象,并从每个工人的访问。 看到这个例子中 ,它不使用数据帧熊猫代替numpy的阵列的相同的事情。

如果你不绝对需要使用Python多,你可以更容易地做到这一点光芒 。 雷的一个优点是,它会开箱不仅与阵列也与包含数组Python对象。

引擎盖下,使用雷序列化Python对象的Apache箭头 ,这是一个零拷贝数据的布局,并且将结果存储在Arrow的等离子体对象存储 。 这使得工人的任务具有只读访问的对象,而无需创建自己的副本。 你可以阅读更多关于如何工作的 。

这里是运行您的示例的修改版本。

import numpy as np
import ray

ray.init()

@ray.remote
def worker_func(data, i):
    # Do work. This function will have read-only access to
    # the data array.
    return 0

data = np.zeros(10**7)
# Store the large array in shared memory once so that it can be accessed
# by the worker tasks without creating copies.
data_id = ray.put(data)

# Run worker_func 10 times in parallel. This will not create any copies
# of the array. The tasks will run in separate processes.
result_ids = []
for i in range(10):
    result_ids.append(worker_func.remote(data_id, i))

# Get the results.
results = ray.get(result_ids)

注意,如果我们省略了线data_id = ray.put(data) ,而是称为worker_func.remote(data, i)data阵列将被存储在共享存储器中每函数调用一次,这将是低效的。 先调用ray.put ,我们可以存储在对象存储的对象一次。



Answer 2:

从概念上对您的问题,使用mmap是一种标准的方式。 以这种方式,信息可以从多个进程映射存储器检索

MMAP的基本认识:

https://en.wikipedia.org/wiki/Mmap

Python有“mmap的”模块( import mmap

Python标准和文档的一些例子在以下链接

https://docs.python.org/2/library/mmap.html



文章来源: python3 multiprocess shared numpy array(read-only)