async在FastAPI中到底是做什么的?

huangapple go评论63阅读模式
英文:

What does async actually do in FastAPI?

问题

我有两个脚本:

from fastapi import FastAPI
import asyncio

app = FastAPI()

@app.get("/")
async def root():
    a = await asyncio.sleep(10)
    return {'Hello': 'World',}

和第二个:

from fastapi import FastAPI
import time

app = FastAPI()

@app.get("/")
def root():
    a = time.sleep(10)
    return {'Hello': 'World',}

请注意第二个脚本没有使用 async。这两个脚本做相同的事情,起初我以为使用 async 的好处是可以同时处理多个连接,但在测试第二段代码时,我也能够运行多个连接。结果是一样的,性能也相同,我不明白为什么要使用 async 方法。感谢您的解释。

英文:

I have two scripts:

from fastapi import FastAPI
import asyncio

app = FastAPI()

@app.get("/")
async def root():
    a = await asyncio.sleep(10)
    return {'Hello': 'World',}

And second one:

from fastapi import FastAPI
import time
  
app = FastAPI()

@app.get("/")
def root():
    a = time.sleep(10)
    return {'Hello': 'World',}

Please note the second script doesn't use async. Both scripts do the same, at first I thought, the benefit of an async script is that it allows multiple connections at once, but when testing the second code, I was able to run multiple connections as well. The results are the same, performance is the same and I don't understand why would we use async method. Would appreciate your explanation.

答案1

得分: 1

FastAPI文档:

> 在路径操作函数中,您可以根据需要混合使用def和async def,并使用最适合您的选项来定义每一个。FastAPI将对它们进行正确处理。
>
> 无论如何,在上述任何情况下,FastAPI仍将异步工作并且执行速度非常快。

两个端点将异步执行,但如果您将端点函数定义为异步,则可以使用await关键字并与异步第三方库一起工作。

英文:

FastAPI Docs:

> You can mix def and async def in your path operation functions as much as you need and define each one using the best option for you. FastAPI will do the right thing with them.
>
> Anyway, in any of the cases above, FastAPI will still work asynchronously and be extremely fast.

Both endpoints will be executed asynchronously, but if you define your endpoint function asynchronously, it will allow you to use await keyword and work with asynchronous third party libraries

答案2

得分: 0

以下是翻译好的部分:

**从另外两个答案中缺少的是:在你的第二个例子中,API 为什么仍然可以处理多个同时的请求。原因可以在 FastAPI 文档的这一部分 中找到:

> 当你使用普通的 def 声明 路径操作函数 而不是 async def 时,它会在外部线程池中运行,然后被等待,而不是直接被调用(因为直接调用会阻塞服务器)。

这意味着所有你的 def 端点都在单独的线程中运行,这就是为什么 API 可以并行化它们。

那么,如果存在这个特性,为什么你还要使用异步呢?你可以阅读比较线程和异步的文章,比如这篇文章,但总结起来,线程的开销更大,而且每个线程仍然会在 IO 操作上被阻塞(比如外部 API 或数据库调用)。**

英文:

What's missing from the two other answers is why in your second example, the API can still handle multiple simultaneous requests. The reason can be found in this section of the FastAPI documentation:

> When you declare a path operation function with normal def instead of async def, it is run in an external threadpool that is then awaited, instead of being called directly (as it would block the server).

Meaning that all your def endpoints are run in separate threads, and that's why the API can parallelize them.

So why would you want to use async at all, if this feature exists? You can read e.g. this article comparing threading and async, but in summary, threads have more overhead, and each thread is still blocked on IO (e.g. external API or database calls).

huangapple
  • 本文由 发表于 2023年2月16日 02:25:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/75463993.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定