concurrent.futures.as_completed是如何工作的?

37

我正在学习Python并发编程,接触到了Future的概念。我看到as_completed()需要一个Future可迭代对象,然后它会在任务完成时将其作为生成器产出。

我想知道它内部是如何工作的。它是否立即产生已完成的任务(Future)?一个朴素的做法是迭代所有Future并使用done()检查每个Future,但这样效率低下。

那么这个函数背后的魔力是什么呢?

谢谢!

1个回答

43
我想知道它的内部工作原理。 as_completed 设置回调函数,用于在所有接收到的future完成时触发。为此,它使用了一个等效于 add_done_callback 的内部API。当任何一个future完成时,as_completed 通过运行其回调函数来得到通知。回调函数在完成future的线程中运行,因此它只设置了一个event,该事件由所有回调函数共享,并且 as_completed 在其上进行睡眠。一旦被事件唤醒,as_completed 立即返回已完成的future。这就是 as_completed 如何确保无论完成顺序如何,future 都会在完成时被返回的方式。在返回后,事件被清除,并且等待过程重复,直到所有futures都完成。
它是否立即返回已完成的任务(futures)?
是的,这符合documented interfaceimplementation的规定。

1
不错的编辑...我在原文中想知道回调函数。 - wwii
如果其中一个协程由于异常而终止会发生什么?当您稍后等待它时,该异常是否会中断迭代行,还是像gather()一样返回它? - Gloweye
已测试,错误会在等待可用协程的行中显示。 - Gloweye
@Gloweye 这里没有协程,这个答案(以及问题)是关于concurrent.futures.as_completed的,它处理多线程,并且与asyncio无关。 - user4815162342
哎呀,这将教训我下次阅读标签。抱歉! - Gloweye

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接