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.result
与f.result(timeout=600)
组合在一起>
,所以它们已经完成。f
...因为
f.result(...)
的迭代在期货完成时欺骗性地等待异步,并且仅将它们返回以使f.result
被称为after
鉴于此,什么是正确的模式来生成as_completed
的列表,其中每个都有自己的超时时间,然后异步等待它们完成?
了解并发超时的文档非常具有挑战性。在一个简单的例子中,我想使用ProcessPoolExecutor通过在循环扫描....>
似乎没有办法在这种异步上下文中提供针对未来的超时。可用的API函数[f.result(timeout=600) for f in as_completed(futures_list)]
和as_completed
通过在.result
对象的可迭代对象中支持所有任务的全局超时来走一条轻松的路,并且不要尝试测量从Future
首次开始活跃起的时间处于正在处理的状态。
我选择了一种解决方法,将任务列表分成一组块,并对每个块使用wait
。块大小设置为与我的as_completed
配置为使用的工作程序数量相同,因此我可以确定Future
的“全局”超时秘密地充当每个未来的超时,因为所有任务都将立即得到积极处理。缺点是利用率较低,因为当任务提早完成时,进程池不能自由地抓住下一个Future任务。它必须等待整个下一批任务。对我来说这是可以的,但是我必须选择Future
,这是严重的可用性缺陷。