python3多进程共享numpy数组(只读)

标签 python python-3.x numpy multiprocessing python-multiprocessing

我不确定这个标题是否适合我的情况:我想分享 numpy array 的原因是它可能是我的情况的潜在解决方案之一,但如果您有其他解决方案,也可以不错。

我的任务:我需要使用多处理实现一个迭代算法,而每个进程都需要有一份数据副本(这个数据很大,并且< strong>只读,并且在迭代算法过程中不会改变)。

我编写了一些伪代码来演示我的想法:

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 数组?或者,如果您很好地实现了解决方案 2,它也可以工作。

提前致谢。

最佳答案

如果您绝对必须使用 Python 多处理,那么您可以将 Python 多处理与 Arrow's Plasma object store 一起使用。将对象存储在共享内存中并从每个工作人员访问它。请参阅this example ,它使用 Pandas 数据框而不是 numpy 数组执行相同的操作。

如果您不是绝对需要使用 Python 多重处理,则可以使用 Ray 更轻松地完成此操作。 。 Ray 的优点之一是它不仅可以开箱即用地处理数组,还可以处理包含数组的 Python 对象。

在底层,Ray 使用 Apache Arrow 序列化 Python 对象,这是一个零拷贝数据布局,并将结果存储在 Arrow's Plasma object store 中。这允许工作任务对对象具有只读访问权限,而无需创建自己的副本。您可以阅读更多关于 how this works .

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

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,我们可以将对象一次性存储在对象存储中。

关于python3多进程共享numpy数组(只读),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54580947/

相关文章:

python - 从 Django sqlite3 数据库中删除对象,减少数据库大小

python - 如何使用 Python 通过 App Function 向 Azure 存储表插入数千行

python-3.x - ValueError : substring not found, 我做错了什么?

linux - 如何在(linux)ubuntu16.04上设置anaconda的代理

python - 从另一个数据框向 Pandas 数据框添加行

numpy - 为什么SVM中支持向量的数量没有变化?

Python 路径分隔符

python网页抓取,提取标签的内部元素

python - iPython:使用 Pandas 计算单词数,如何计算最少出现的单词?

python - 使用 numpy 求解整数线性系统