【发布时间】:2021-09-05 16:47:18
【问题描述】:
我有一个函数,我使用 Pool.starmap() 调用 n 进程。我想在n 中的任何k 完成后终止所有进程。我该如何实现?
【问题讨论】:
标签: python multiprocessing pool terminate
我有一个函数,我使用 Pool.starmap() 调用 n 进程。我想在n 中的任何k 完成后终止所有进程。我该如何实现?
【问题讨论】:
标签: python multiprocessing pool terminate
使用Pool.imap_unordered 或concurrent.futures.as_completed 在list 提交的任务上更容易做到这一点。无论哪种情况,解决方案都是相同的;迭代生成的迭代器k 次(例如使用itertools.slice),然后终止Pool(在Executor 的情况下,调用shutdown(cancel_futures=True),或确保手动取消所有未完成的任务)。例如,而不是:
with Pool() as pool:
results = pool.starmap(func, makes_tuples())
将所有结果收集为单个操作并消除您在中途停止处理的能力,您可以这样做:
from itertools import islice
# Defined at global scope as simple wrapper to allow non-starmap functions to
# be used with iterators of argument tuples
def starcall_func(args):
return func(*args)
...
with Pool() as pool:
results = list(islice(pool.imap_unordered(starcall_func, makes_tuples()), k))
# When with exits, pool is terminated automatically, and only k results were collected
【讨论】:
shutdown 方法发明了cancel_futures 关键字参数?我不相信concurrent.futures.Executor 提供任何终止已启动任务的方法。在尚未启动的Future 实例上调用cancel将阻止它启动,但这并不完全相同。我会坚持在 multiprocessing.pool.Pool 实例上调用 terminate。
cancel_futures 是在 3.9 中引入的,所以是的,它很新,你以前不能使用它(当然,在这种情况下,你有一个所有期货的集合,所以你可以很容易地自己取消它们)。是的,它不会在中间停止任务,所以你能得到的最接近的是cancel_futures=True加上wait=False,它可以取消它可以做的事情并且不会让你阻止当前正在运行的事情;它让他们完成然后关闭商店。 terminate(或等效地,退出控制 Pool 的 with 块)是最激进的解决方案。