Why is asyncio.Future incompatible with concurrent.futures.Future?
这两个类代表了并发编程的出色抽象,因此令人不安的是它们不支持相同的API。
具体来说,根据文档:
asyncio.Future is almost compatible withconcurrent.futures.Future .Differences:
result() andexception() do not take a timeout argument and raise an exception when the future isn’t done yet.- Callbacks registered with
add_done_callback() are always called via the event loop'scall_soon_threadsafe() .- This class is not compatible with the
wait() andas_completed() functions in theconcurrent.futures package.
上面的清单实际上是不完整的,还有更多区别:
running() method is absentresult() andexception() may raiseInvalidStateError if called too early
这些事件是否是由于事件循环的固有性质而导致的,这些事件使这些操作变得无用或难以实施?
与
差异的核心原因在于线程(和进程)如何处理块以及协程如何处理块的事件。在线程化过程中,当前线程将被挂起,直到任何情况解决并且线程可以前进。例如,在期货的情况下,如果您请求期货的结果,则可以暂停当前线程,直到该结果可用为止。
但是,事件循环的并发模型是返回到事件循环,并在准备就绪时再次调用它,而不是暂停代码。因此,请求尚未准备好结果的异步将来的结果是错误的。
您可能会认为asyncio的未来可能会等待,尽管那会效率低下,但您的协程被阻止真的那么糟糕吗?事实证明,拥有协程封锁很可能意味着未来永远不会完成。将来的结果很有可能将由一些与运行请求结果的代码的事件循环关联的代码设置。如果运行该事件循环的线程阻塞,则不会运行与该事件循环关联的代码。因此,阻塞结果将导致死锁并阻止产生结果。
因此,是的,界面差异是由于这种固有差异而引起的。例如,您不希望将asyncio future与并发.futures服务员抽象一起使用,因为这又会阻塞事件循环线程。
这些对象(以及许多其他线程/异步对象,例如
我认为对象不同的主要原因是历史原因:
两种阶级都应该在"理想世界"中合而为一吗?这可能是值得商bat的问题,但我看到了许多缺点:虽然乍一看
我认为类别最好可能是最好的:我们清楚地区分了不同的并发方式(即使它们的相似性乍看起来很奇怪)。