当独立网络调用不应该互相阻塞时,async/await 很有用[重复]

问题描述 投票:0回答:1

我对 Python 的 asyncio 库(以及一般 Python 的异步函数)的理解是它使用线程。这些线程不是进程,因此不可能进行CPU划分和并行化。

但是,如果应用程序方法有两个网络调用 A 和 B,则可能合适。如果 A 必须在 B 开始之前完成,那么我的理解是使用 async/await 语法是浪费精力。但是,如果 A 和 B 是独立的(两个响应都不是另一个响应的输入),那么 async/await 语法确实很有用。原因是网络调用 A 的执行处于空闲时间,从而阻塞了网络调用 B 的启动。Async/await 将允许 B 在收到 A 的响应之前开始。

我可能是错的,但这是我的理解。我越来越多地看到 FastAPI 教程、博客等在假定不会对性能造成损害但也没有用的上下文中使用 async/await。 一个例子。其中许多调用都定向到服务自己的关系数据库。当 async/await 有用/没用时,这可能会变得复杂。

我的理解准确吗?

python async-await fastapi
1个回答
1
投票

我对Python的

asyncio
库的理解是它使用线程

不。或者更确切地说,不一定。异步与线程无关

这些线程不是进程,因此不可能进行CPU划分和并行化

同样错误的是,线程可以并且确实在不同的 CPU 上运行,尽管同样

asyncio
不一定使用线程。由于 GIL,Python 中的线程无法实现并行化,但这通常不适用于多线程。如果您想要真正的并行处理,请查看标准库中的multiprocessing模块。

您对何时选择 asyncio 的理解基本上是正确的:任何时候您有一个具有大量空闲时间的 I/O 绑定进程(例如等待用户输入、等待 TLS 握手等),将其包装在异步任务中可以让其他代码运行。考虑您链接的示例中的代码:

  • 与数据库对话是 I/O*
  • 与另一个服务(甚至是你自己的服务!)对话是 I/O

除了这些

  • 获取用户输入(I/O)
  • 与文件系统或操作系统(I/O)对话

asyncio
往往有益的事物。

相比之下,用 numpy 处理一堆数字并不是 I/O。如果您需要处理一堆数字,并且计算能够独立并行化,那么您希望将并行性与多处理结合使用。

* 请注意,虽然

数据库本身可能受 CPU 限制,但通过套接字查询(远程或本地)是 I/O:您大部分时间都在等待应用程序层的响应数据包。

© www.soinside.com 2019 - 2024. All rights reserved.