Python Pool.Starmap 未在打印时终止或输出
Posted
技术标签:
【中文标题】Python Pool.Starmap 未在打印时终止或输出【英文标题】:Python Pool.Starmap Not Terminating Or Outputting on Print 【发布时间】:2021-12-23 12:20:38 【问题描述】:我尝试了几种不同的方式来执行Pool.starmap
。我尝试了各种不同的建议和答案,但无济于事。下面是我尝试运行的代码示例,但是它被捕获并且永远不会终止。我在这里做错了什么?
旁注:我使用的是python版本3.9.8
if __name__ == '__main__':
with get_context("spawn").Pool() as p:
tasks = [(1,1),(2,2),(3,3)]
print(p.starmap(add,tasks))
p.close()
p.join()
【问题讨论】:
当为Pool
使用with
上下文时,您不需要close
或join
池。这就是 with
上下文为您所做的。
【参考方案1】:
python 中的多处理具有一些您应该注意的复杂性,这使得它取决于您运行脚本的方式以及您使用的操作系统和 python 版本。
我经常看到的一个大问题是 Jupyter 和其他“笔记本”风格的 Python 环境并不总是能很好地支持多处理。从技术上讲,有一些方法可以解决这个问题,但我通常只是建议从更正常的系统终端执行代码。共同点是“交互式”解释器不能很好地工作,因为需要有一个“主”文件,而在交互模式下没有文件;它只是等待用户输入。
我无法确切知道您的问题是什么,因为您没有提供所有代码、您正在使用的操作系统以及您正在使用的 IDE,但我至少可以为您提供一个工作 (在我的设置上)示例。 (windows 10;python 3.9;带有运行设置的 Spyder IDE -> 在外部系统终端中执行)
import multiprocessing as mp
def add(a, b): #I'm assuming your "add" function looks a bit like this...
return a+b
if __name__ == "__main__":
#this is critical when using "spawn" so code doesn't run when the file is imported
#you should only define functions, classes, and static data outside this (constants)
#most critically, it shouldn't be possible for a new child process to start outside this
ctx = mp.get_context("spawn")
#This is the only context available on windows, and the default for MacOS since python 3.8.
# Contexts are an important topic somewhat unique to python multiprocessing, and you should
# absolutely do some additional reading about "spawn" vs "fork". tldr; "spawn" starts a new
# process with no knowledge of the old one, and must `import` everything from __main__.
# "fork" on the other hand copies the existing process and all its memory before branching. This is
# faster than re-starting the interpreter, and re-importing everything, but sometimes things
# get copied that shouldn't, and other things that should get copied don't.
with ctx.Pool() as p:
#using `with` automatically shuts down the pool (forcibly) at the end of the block so you don't have to call `close` or `join`.
# It was also pointed out that due to the forcible shutdown, async calls like `map_async` may not finish unless you wait for the results
# before the end of the `with` block. `starmap` already waits for the results in this case however, so extra waiting is not needed.
tasks = [(1,1),(2,2),(3,3)]
print(p.starmap(add, tasks))
【讨论】:
一个小点:退出with
块只会调用p.terminate()
,所以如果有任何任务正在运行或计划运行,它们将被杀死。
@Booboo TIL...谢谢!但是,starmap
在这种情况下是同步的,因此无论如何都应该完成所有处理。但是,对于 Pool
的任何异步函数,了解这一点很重要。它遵循这样的做法:在 join
处理进程(或本例中的池)之前,您应该始终从队列中得到 get
结果。以上是关于Python Pool.Starmap 未在打印时终止或输出的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Pool.starmap_async() 中获取结果?