关于python:为什么asyncio.Future与parallel.futures.Future不兼容?

Why is asyncio.Future incompatible with concurrent.futures.Future?

这两个类代表了并发编程的出色抽象,因此令人不安的是它们不支持相同的API。

具体来说,根据文档:

asyncio.Future is almost compatible with concurrent.futures.Future.

Differences:

  • result() and exception() 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's call_soon_threadsafe().
  • This class is not compatible with the wait() and as_completed() functions in the concurrent.futures package.

上面的清单实际上是不完整的,还有更多区别:

  • running() method is absent
  • result() and exception() may raise InvalidStateError if called too early

这些事件是否是由于事件循环的固有性质而导致的,这些事件使这些操作变得无用或难以实施?

add_done_callback()相关的区别是什么意思? 无论哪种方式,都保证了在期货交易完成后的某个未指定时间发生回调,所以这两个类之间的一致性不是很好吗?


差异的核心原因在于线程(和进程)如何处理块以及协程如何处理块的事件。在线程化过程中,当前线程将被挂起,直到任何情况解决并且线程可以前进。例如,在期货的情况下,如果您请求期货的结果,则可以暂停当前线程,直到该结果可用为止。

但是,事件循环的并发模型是返回到事件循环,并在准备就绪时再次调用它,而不是暂停代码。因此,请求尚未准备好结果的异步将来的结果是错误的。

您可能会认为asyncio的未来可能会等待,尽管那会效率低下,但您的协程被阻止真的那么糟糕吗?事实证明,拥有协程封锁很可能意味着未来永远不会完成。将来的结果很有可能将由一些与运行请求结果的代码的事件循环关联的代码设置。如果运行该事件循环的线程阻塞,则不会运行与该事件循环关联的代码。因此,阻塞结果将导致死锁并阻止产生结果。

因此,是的,界面差异是由于这种固有差异而引起的。例如,您不希望将asyncio future与并发.futures服务员抽象一起使用,因为这又会阻塞事件循环线程。

add_done_callbacks差异保证了回调将在事件循环中运行。这是可取的,因为它们将获取事件循环的线程本地数据。而且,许多协程代码都假定它永远不会与来自同一事件循环的其他代码同时运行。也就是说,协程仅在来自同一事件循环的两个协程不在同一时间运行的假设下才是线程安全的。在事件循环中运行回调避免了很多线程安全问题,并使编写正确的代码更加容易。


concurrent.futures.Future提供了一种通常在使用Executor时在不同线程和进程之间共享结果的方法。

asyncio.Future解决了相同的任务,但对于协程,它们实际上是通常在一个进程/线程中异步运行的某些特殊功能。当前上下文中的"异步"意味着事件循环管理该协程的代码执行流:它可以挂起一个协程内部的执行,开始执行另一个协程,然后返回执行第一个协程-通常所有事情都在一个线程/进程中执行。

这些对象(以及许多其他线程/异步对象,例如LockEventSemaphore等)看起来很相似,因为代码与线程/进程和协程的并发性思想相似。

我认为对象不同的主要原因是历史原因:asyncio的创建时间远晚于threadingconcurrent.futures。在不破坏类API的情况下,更改concurrent.futures.Future以与asyncio一起使用可能是不可能的。

两种阶级都应该在"理想世界"中合而为一吗?这可能是值得商bat的问题,但我看到了许多缺点:虽然乍一看asynciothreading看起来很相似,但是它们在很多方面都非常不同,包括内部实现或编写异步/非异步代码的方式(请参见async / await关键字)。

我认为类别最好可能是最好的:我们清楚地区分了不同的并发方式(即使它们的相似性乍看起来很奇怪)。