asyncio是 Python 标准库中的一个模块,用于编写异步 I/O 操作的代码。asyncio 提供了一种高效的方式来处理并发任务,特别适用于 I/O 密集型操作,如网络请求、文件读写等。
通过使用
asyncio,你可以在单线程中同时处理多个任务,而无需使用多线程或多进程。为什么需要 asyncio?
在传统的同步编程中,当一个任务需要等待 I/O 操作(如网络请求)完成时,程序会阻塞,直到操作完成。这会导致程序的效率低下,尤其是在需要处理大量 I/O 操作时。
asyncio通过引入异步编程模型,允许程序在等待 I/O 操作时继续执行其他任务,从而提高了程序的并发性和效率。
asyncio 的核心概念
1. 协程(Coroutine)
协程是 asyncio 的核心概念之一。它是一个特殊的函数,可以在执行过程中暂停,并在稍后恢复执行。协程通过 async def 关键字定义,并通过 await 关键字暂停执行,等待异步操作完成。
实例
2. 事件循环(Event Loop)
事件循环是 asyncio 的核心组件,负责调度和执行协程。它不断地检查是否有任务需要执行,并在任务完成后调用相应的回调函数。
实例
async def main():
await say_hello()
asyncio.run(main())
3. 任务(Task)
任务是对协程的封装,表示一个正在执行或将要执行的协程。你可以通过 asyncio.create_task() 函数创建任务,并将其添加到事件循环中。
实例
async def main():
task = asyncio.create_task(say_hello())
await task
4. Future
Future 是一个表示异步操作结果的对象。它通常用于底层 API,表示一个尚未完成的操作。你可以通过 await 关键字等待 Future 完成。
实例
async def main():
future = asyncio.Future()
await future
asyncio 的基本用法
1. 运行协程
要运行一个协程,你可以使用 asyncio.run() 函数。它会创建一个事件循环,并运行指定的协程。
实例
2. 并发执行多个任务
你可以使用 asyncio.gather() 函数并发执行多个协程,并等待它们全部完成。
实例
import asyncio
async def task1():
print("Task 1 started")
await asyncio.sleep(1)
print("Task 1 finished")
async def task2():
print("Task 2 started")
await asyncio.sleep(2)
print("Task 2 finished")
async def main():
await asyncio.gather(task1(), task2())
asyncio.run(main())
3. 超时控制
你可以使用 asyncio.wait_for() 函数为协程设置超时时间。如果协程在指定时间内未完成,将引发 asyncio.TimeoutError 异常。
实例
import asyncio
async def long_task():
await asyncio.sleep(10)
print("Task finished")
async def main():
try:
await asyncio.wait_for(long_task(), timeout=5)
except asyncio.TimeoutError:
print("Task timed out")
asyncio.run(main())
asyncio 的应用场景
asyncio 特别适用于以下场景:
- 网络请求:如 HTTP 请求、WebSocket 通信等。
- 文件 I/O:如异步读写文件。
- 数据库操作:如异步访问数据库。
- 实时数据处理:如实时消息队列处理。
# 协程
import asyncio
async def getPhone(name):
print("开始获取手机号")
await asyncio.sleep(1)
print("获取手机号成功")
async def getName():
print("开始获取姓名")
await asyncio.sleep(0.5)
print("获取姓名成功")
async def main():
# 同步方式
# phone=await getPhone("张三")
# name=await getName()
# 异步方式1
# await asyncio.gather(getPhone("张三"),getName())
# 异步方式2
task1= asyncio.create_task(getPhone("张三"))
task2= asyncio.create_task(getName())
await task1
await task2
asyncio.run(main())
1330

被折叠的 条评论
为什么被折叠?



