【问题标题】:Why does my Python multiprocessing result not append on callback?为什么我的 Python 多处理结果没有附加到回调上?
【发布时间】:2021-03-16 23:12:49
【问题描述】:

我似乎无法弄清楚为什么我的结果在使用多处理包时没有附加。

我查看了许多类似的问题,但似乎无法弄清楚我做错了什么。这是我第一次尝试多处理(你可能会说)所以我不太了解文档中可能是问题的一部分的所有行话

在 PyCharm 中运行它会打印一个空列表,而不是所需的行总和列表。

import numpy as np
from multiprocessing import Pool
import timeit

data = np.random.randint(0, 100, size=(5, 1000))


def add_these(numbers_to_add):
    added = np.sum(numbers_to_add)
    return added


results = []
tic = timeit.default_timer()  # start timer

pool = Pool(3)
if __name__ == '__main__':
    for row in data:
        pool.apply_async(add_these, row, callback=results.append)


toc = timeit.default_timer()  # start timer
print(toc - tic)
print(results)  

编辑:关闭并加入池,然后在 if name==main 块中打印结果会导致重复引发以下错误,直到我手动停止执行:

运行时错误: 在当前进程完成其引导阶段之前,已尝试启动一个新进程。这可能意味着您没有使用 fork 来启动子进程,并且您忘记了在主模块中使用正确的习惯用法:

        if __name__ == '__main__':
            freeze_support()
            ...

如果程序不会被冻结以生成可执行文件,则可以省略“freeze_support()”行。

重现错误的代码:

import numpy as np
from multiprocessing import Pool, freeze_support
import timeit

data = np.random.randint(0, 100, size=(5, 1000))


def add_these(numbers_to_add):
    added = np.sum(numbers_to_add)
    return added


results = []
tic = timeit.default_timer()  # start timer

pool = Pool(3)
if __name__ == '__main__':
    for row in data:
        pool.apply_async(add_these, (row,), callback=results.append)
    pool.close()
    pool.join()
    print(results)


toc = timeit.default_timer()  # end timer
print(toc - tic)

【问题讨论】:

  • 所以您已经启动了一些进程,这些进程将在未来的某个时间附加到result - 然后您立即打印出result,而无需等待这些进程执行任何操作。在尝试查看结果之前,您应该先调用 pool.close(),然后再调用 pool.join()
  • @jasonharper 嗯,如果我在 print(results) 之前添加 pool.close() 和 pool.join(),那么我会得到一个 RunTimeError -“之前已经尝试启动一个新进程当前进程已完成其引导阶段。这可能意味着您没有使用 fork 来启动子进程,并且您忘记在主模块中使用正确的习惯用法: if name == 'main': freeze_support() ... 如果程序不会被冻结以生成可执行文件,则可以省略“freeze_support()”行。
  • 涉及池的所有内容,包括打印结果,都需要在 if __name__ == '__main__': 块内。在该块之外唯一有效的东西是函数定义
  • 好的,我将它们放在 if name == '__main': 块中,但我仍然遇到同样的错误(请参阅问题编辑)

标签: python multiprocess


【解决方案1】:

我认为这样会更正确:

import numpy as np
from multiprocessing import Pool
import timeit

data = np.random.randint(0, 100, size=(5, 1000))


def add_these(numbers_to_add):
    added = np.sum(numbers_to_add)
    return added


results = []

if __name__ == '__main__':
    with Pool(processes=3) as pool:
        for row in data:
            results = pool.apply_async(add_these, (row,))
            try:
                print(results.get(timeout=1))
            except TimeoutError:
                print("Multiprocessing Timeout")

【讨论】:

  • 这个答案没有帮助。您应该提供有关此代码为何以及如何工作的说明。只是一个友好的建议。
  • 嗯,这似乎确实有效,但是当我将数据大小增加到 size=(500, 100000) 时,尽管尝试了除外,但我得到了 TimoutError。
  • @thposs 尝试增加 timeout=2 或更高。
  • 好的,很好,谢谢。超时参数代表什么?单位是秒吗?意思是,在尝试获得结果之前等待 x 秒数? - 编辑:好的找到文档,它确实代表秒。
猜你喜欢
  • 1970-01-01
  • 2015-10-15
  • 2013-05-31
  • 2020-05-20
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 2014-06-29
  • 1970-01-01
相关资源
最近更新 更多