我已经给了concurrent.futures.ThreadPoolExecutor
一堆任务,我想等到它们全部完成后再继续流程。我怎么能这样做,而不必保存所有的期货并打电话给wait
? (我想对执行者采取行动。)
答案 0 :(得分:25)
只需致电Executor.shutdown
:
<强>
shutdown(wait=True)
强>告知执行者它应该释放它所有的资源 在当前待处理的期货执行时使用。呼叫 在关机后制作
Executor.submit()
和Executor.map()
提高RuntimeError
。如果等待
True
,那么在所有未决期货到期之前,此方法不会返回 完成执行并释放与执行程序关联的资源。
但是,如果您在列表中跟踪您的未来,那么您可以避免使用futures.wait()
函数关闭执行程序以备将来使用:
<强>
concurrent.futures.wait(fs, timeout=None, return_when=ALL_COMPLETED)
强>等待
Future
个实例(可能由不同的实例创建) 由Executor
完成的fs
个实例)。返回一个命名的2元组 集合。名为done的第一组包含期货 在等待完成之前完成(完成或取消)。该 名为not_done的第二组包含未完成的期货。
请注意,如果您未提供timeout
,则等待所有期货完成。
您也可以使用futures.as_completed()
,但是您必须迭代它。
答案 1 :(得分:8)
Bakuriu的回答是正确的。只是延伸一点点。我们都知道上下文管理器有__enter__
和__exit__
方法。以下是class Executor
( ThreadPoolExecutor的基类)的定义方式
class Executor(object):
# other methods
def shutdown(self, wait=True):
"""Clean-up the resources associated with the Executor.
It is safe to call this method several times. Otherwise, no other
methods can be called after this one.
Args:
wait: If True then shutdown will not return until all running
futures have finished executing and the resources used by the
executor have been reclaimed.
"""
pass
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.shutdown(wait=True)
return False
实际定义ThreadPoolExecutor
方法
shutdown
class ThreadPoolExecutor(_base.Executor):
def shutdown(self, wait=True):
with self._shutdown_lock:
self._shutdown = True
self._work_queue.put(None)
if wait:
for t in self._threads:
t.join()
答案 2 :(得分:0)
如前所述,可以使用Executor.shutdown(wait=True)
,但也请注意文档中的以下注意事项:
如果使用
with
语句,可以避免显式调用此方法,这将关闭Executor
(等待Executor.shutdown()
被调用将wait
设置为True
):import shutil with ThreadPoolExecutor(max_workers=4) as e: e.submit(shutil.copy, 'src1.txt', 'dest1.txt') e.submit(shutil.copy, 'src2.txt', 'dest2.txt') e.submit(shutil.copy, 'src3.txt', 'dest3.txt') e.submit(shutil.copy, 'src4.txt', 'dest4.txt')