821 字
4 分钟
并发 async/await
2024-12-28

如果你正在使用一个第三方库进行通信,而这个库又不支持 await,那么可以使用正常的 def 声明一个函数

注意:你可以根据需要在路径操作函数中混合使用 def 和 async def,并使用最适合你的方式去定义每个函数。FastAPI 将为他们做正确的事情。无论如何,在上述任何情况下,FastAPI 仍将异步工作,速度也非常快。但是,通过遵循上述步骤,它将能够进行一些性能优化。

技术细节#

python 现代版本支持一种叫协程的技术,使用 async 和 await 来写异步代码

异步代码#

异步代码表示编程语言告诉计算机代码中的某个点不得不等待一些事情,比如等待一个文件 IO,网络通信 (IO 密集型任务),在这个等待过程中,计算机可以做一些别的事情,计算机每次有机会回来,就会检查所有等待的任务有没有已经完成的.

它被称为异步是因为计算机不必与慢任务同步,去等待任务完成的具体时间,而在这个期间不做任何事情.作为一个异步系统,计算机可以排队等待一段时间,然后回来取回结果.

并发与并行#

并行就是每个线程都等着,并发就是减少等待的一种手段.

对于 web 服务器来说,并发系统的意义更大,因为他能减少等待的时间长度.服务器等待用户发来请求,然后做一些事情 (比如等待数据库响应).这就是 nodejs 和 go 的优势所在.使用 fastapi,可以获得和 golang 差不多的并发性能.

并发并不一定比并行好,只是在需要大量等待的特定场景更好,因此在 web 的开发中,并发比并行要好得多. 而在另一些场景中,比如打扫一个巨大的屋子,在任何地方都不需要等待,只是需要做很多很多的工作,不需要等待,无论需不需要轮询,都需要相同的时间来完成,这个叫 cpu 密集型任务,在这种任务中使用并行是没有意义的.

Async 和 Await#

现版本的 python 有一种直观的方式来定义异步代码,让他和顺序代码一样,并且在适当的时候等待.当一个操作需要等待才能给出结果,可以编写以下代码

burgers = await get_burgers(2)

这里的关键是这个 await,他告诉 python 这里必须等待才能完成他的工作,要使用 await,必须封装在 async 中

async def get_burgers(number:int):
	return await get_burgers(2)

@app.get('/burgers')
async def read_burgers():
	burgers = await get_burgers(2)
	return burgers

这里我们可以看到 await 只能在 async def 中使用,而 async def 也只能在 async def 的函数内部调用,这就是先有鸡还是先有蛋的问题.如果使用 fastapi 不用担心这一点

协程#

协程只是 async def 函数返回的一个东西的称呼,python 知道他有点像一个函数,可以启动,也可以暂停或结束

并发 async/await
https://fuwari.vercel.app/posts/编程语言/python小技巧/fastapi/并发/
作者
FlyingWhite
发布于
2024-12-28
许可协议
CC BY-NC-SA 4.0