如何在并发.futures的迭代器中确保每个Future都有超时?

问题描述 投票:1回答:1

documentation的超时周围的concurrent.futures很难理解。在一个简单的情况下,我想在循环扫描作业功能列表的循环中调用ProcessPoolExecutor来使用.submit。我希望这些Future对象中的每一个都具有10分钟的关联超时,否则,它们将以异步方式完成。

[我的第一种方法是尝试使用as_completed函数,该函数生成Future对象的迭代器,并且仅在完成时才生成下一个。 as_completed接受as_completed参数,但是文档指出此超时与timeout调用的第一时刻有关,而不一定与任何as_completed对象本身的生存期有关。

例如假设Future只有3个工作进程,但是ProcessPoolExecutor对象的列表包含10个项目。在处理前3个项目时,其中7个项目可能处于未处理状态长达10分钟。此后不久,即使每个Future可能自己都已达到10分钟的限制,从as_completed开始的超时也会跳闸,从而导致失败。

请注意,与Future相同的限制也将适用于as_completed,并且由于其支持的返回选项有限,因此在此用例中更难以使用wait

[我的下一个想法是使用wait,并为我的期货清单中的每个wait(期货)调用timeout parameter that future.result allows。但是,实际上没有一种方法可以设置该超时时间,而无需实际以阻塞方式要求结果。如果您迭代期货列表并调用timeout,则此调用将在指定的超时时间内阻止。

另一方面,您也不能以一种幼稚但看似正确的方式将future.resultf.result(timeout=600)组合在一起>

f

...因为f.result(...)的迭代在期货完成时欺骗性地等待异步,并且仅将它们返回以使f.result被称为after

,所以它们已经完成。

鉴于此,什么是正确的模式来生成as_completed的列表,其中每个都有自己的超时时间,然后异步等待它们完成?

了解并发超时的文档非常具有挑战性。在一个简单的例子中,我想使用ProcessPoolExecutor通过在循环扫描....>

python python-3.x asynchronous timeout concurrent.futures
1个回答
0
投票

似乎没有办法在这种异步上下文中提供针对未来的超时。可用的API函数[f.result(timeout=600) for f in as_completed(futures_list)] as_completed通过在.result对象的可迭代对象中支持所有任务的全局超时来走一条轻松的路,并且不要尝试测量从Future首次开始活跃起的时间处于正在处理的状态。

我选择了一种解决方法,将任务列表分成一组块,并对每个块使用wait。块大小设置为与我的as_completed配置为使用的工作程序数量相同,因此我可以确定Future的“全局”超时秘密地充当每个未来的超时,因为所有任务都将立即得到积极处理。缺点是利用率较低,因为当任务提早完成时,进程池不能自由地抓住下一个Future任务。它必须等待整个下一批任务。对我来说这是可以的,但是我必须选择Future,这是严重的可用性缺陷。

© www.soinside.com 2019 - 2024. All rights reserved.