gpt4 book ai didi

python - 为什么 asyncio.Future 与 concurrent.futures.Future 不兼容?

转载 作者:太空狗 更新时间:2023-10-29 20:17:59 29 4
gpt4 key购买 nike

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

具体根据docs :

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() 相关的差异是什么意思?无论哪种方式,回调都保证在 future 完成后的某个未指定时间发生,所以这两个类之间不是完全一致吗?

最佳答案

差异的核心原因在于线程(和进程)处理 block 的方式与协程处理 block 事件的方式。在线程中,当前线程被挂起,直到任何条件解决并且线程可以继续前进。例如在 future 的情况下,如果您请求 future 的结果,则可以挂起当前线程直到该结果可用。

然而,事件循环的并发模型不是挂起代码,而是返回事件循环并在准备就绪时再次调用。因此,请求没有准备好结果的 asyncio future 的结果是错误的。

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

所以,是的,界面的差异是由于这种内在差异造成的。例如,您不想将 asyncio future 与 concurrent.futures 服务员抽象一起使用,因为这同样会阻塞事件循环线程。

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

关于python - 为什么 asyncio.Future 与 concurrent.futures.Future 不兼容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43882301/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com