具有 numpy 函数的多处理池

Posted

技术标签:

【中文标题】具有 numpy 函数的多处理池【英文标题】:Multiprocessing pool with numpy functions 【发布时间】:2021-05-14 17:24:17 【问题描述】:

我有一台 6 核的 i5-8600k,并且正在运行一台 Windows 10 计算机。我正在尝试使用 2 个 numpy 函数执行多处理。我事先提出了一个问题,但我没有成功运行该问题:issue,下面的代码来自该问题的答案。我正在尝试同时运行func1()func2(),但是当我运行下面的代码时,它会一直运行下去。

import multiprocessing as mp
import numpy as np
num_cores = mp.cpu_count()

Numbers = np.array([1,2,3,4,5,6,7,8,9,10,11,12])
def func1():
     Solution_1 = Numbers + 10
     return Solution_1
def func2():
     Solution_2 = Numbers * 10
     return Solution_2

# Getting ready my cores, I left one aside
pool = mp.Pool(num_cores-1)
# This is to use all functions easily
functions = [func1, func2]
# This is to store the results
solutions = []
for function in functions:
    solutions.append(pool.apply(function, ()))

【问题讨论】:

在具有非常旧处理器的 Linux Mint 上运行时间不到 0.03 秒。但我正常运行它python script.py,而不是在 Jupyter Notebook 中。 它是否有可能无法在使用 pythons 内核的 jupyter notebook 上运行? 是的,多处理需要导入 __main__ 模块,这在交互式会话中是不可能的:***.com/a/23641560/3220135 interactive 非常适合原型设计和探索性分析,但不适用于实际运行您构建的代码 现在我在 Jupiter Notebook 中测试了它,它可以在 0.05 秒内运行。顺便说一句:在这两个版本中,我都必须添加 print(solutions) 才能看到结果。 【参考方案1】:

代码有几个问题。首先,如果你想在 Windows 的 Jupyter Notebook 下运行它,那么你需要将你的工作函数 func1func2 放在一个外部模块中,例如 workers.py 并导入它们,这意味着你现在需要要么将 Numbers 数组作为参数传递给工作人员,或者在初始化池时使用数组初始化每个进程的静态存储。我们将为您介绍第二种方法,其函数名为init_pool,如果我们在 Notebook 下运行,也必须导入该函数:

workers.py

def func1():
     Solution_1 = Numbers + 10
     return Solution_1

def func2():
     Solution_2 = Numbers * 10
     return Solution_2

def init_pool(n_array):
    global Numbers
    Numbers = n_array

第二个问题是,在 Windows 下运行时,创建子进程或多处理池的代码必须位于由条件 if __name__ == '__main__': 管理的块内。第三,如果您只尝试运行两个并行“作业”,则创建大于 2 的池大小是浪费的。第四,我认为最后,您使用了错误的池方法。 apply 将阻塞,直到提交的“作业”(即由func1 处理的作业)完成,因此您根本没有达到任何程度的并行性。你应该使用apply_async

import multiprocessing as mp
import numpy as np
from workers import func1, func2, init_pool


if __name__ == '__main__':
    #num_cores = mp.cpu_count()
    Numbers = np.array([1,2,3,4,5,6,7,8,9,10,11,12])
    pool = mp.Pool(2, initializer=init_pool, initargs=(Numbers,)) # more than 2 is wasteful
    # This is to use all functions easily
    functions = [func1, func2]
    # This is to store the results
    solutions = []
    results = [pool.apply_async(function) for function in functions]
    for result in results:
        solutions.append(result.get()) # wait for completion and get the result
    print(solutions)

打印:

[array([11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]), array([ 10,  20,  30,  40,  50,  60,  70,  80,  90, 100, 110, 120])]

【讨论】:

谢谢它确实有效,但是我无法让它与 jupyter 一起工作我在 jupyter 内核上运行 python 3.7.8 有没有办法让它与该程序一起工作? 我不确定您的问题是什么。我在 Windows 10 下运行 Python 3.8.5,这在 Jupyter Notebook 和 Jupyter Lab 下运行良好。我已在我的答案中附上了一张图片。您需要更详细地描述“我无法使其工作”的含义。例如,您是否在 Jupyter Notebook 控制台上看到错误? 这表明那段代码一直在运行我不知道为什么。我已经用显示星号正在运行的快照更新了代码。 我的回答明确指出函数func1func2init_pool必须放在一个模块中并导入。重新阅读我的答案描述并重新阅读我的代码。我将这些文件放在与包含我的单元格的.ipynb 文件相同的目录中的文件workers.py 中。如果您查看启动 Notebook 的“控制台”,如果不这样做,您会看到很多错误消息。 我认为没有必要,所以我在一个 python 文件中运行了所有函数。它适用于script.py,但不适用于 jupyter notebook。我不太明白

以上是关于具有 numpy 函数的多处理池的主要内容,如果未能解决你的问题,请参考以下文章

没有参数/可迭代的函数的多处理池?

如果从函数内部执行,带有“apply_async”的多处理池啥也不做

多处理 - 具有多维 numpy 数组的共享内存

如何根据工作人员结果将额外任务添加到正在运行的多处理池中?

使用 NumPy 在 Python 中进行简单的多处理

python的多处理池的键盘中断