asyncio
是 Python 用来编写 异步IO(Asynchronous I/O)程序的标准库,特别适合 处理高并发的 IO 密集型任务,比如网络请求、文件读取等。
与传统的多线程不同,asyncio
使用 协程(coroutines) 和 事件循环(event loop) 来实现并发,能更高效地利用资源。
简单理解
async def
定义协程函数await
等待耗时操作完成asyncio.run()
启动事件循环并运行主协程
示例:模拟两个异步任务并发执行
import asyncio
import time
async def task(name, delay):
print(f"{name} 开始")
await asyncio.sleep(delay) # 模拟异步耗时操作
print(f"{name} 完成,耗时 {delay} 秒")
async def main():
# 并发执行两个任务
await asyncio.gather(
task("任务1", 2),
task("任务2", 3)
)
start = time.time()
asyncio.run(main())
print(f"总耗时: {time.time() - start:.2f} 秒")
输出示例
任务1 开始
任务2 开始
任务1 完成,耗时 2 秒
任务2 完成,耗时 3 秒
总耗时: 3.00 秒
重点
- 如果是同步写法,两个任务会顺序执行,总共需要 5 秒。
asyncio.gather()
并发执行多个协程,所以总耗时是最长的那个:3 秒。
下面是一个 手动管理事件循环 的 asyncio
示例,展示了如何不用 asyncio.run()
,而是通过手动创建、运行、关闭事件循环,并使用 asyncio.Event
来实现两个任务之间的通信。
示例:一个任务等待“事件”发生,另一个任务触发事件
import asyncio
async def waiter(event):
print("waiter: 等待事件触发...")
await event.wait() # 阻塞直到事件被 set()
print("waiter: 事件已触发,继续执行")
async def setter(event):
print("setter: 3 秒后触发事件")
await asyncio.sleep(3)
event.set()
print("setter: 事件已触发")
# 手动管理事件循环
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
event = asyncio.Event()
try:
# 手动运行事件循环,直到两个任务都完成
loop.run_until_complete(
asyncio.gather(waiter(event), setter(event))
)
finally:
loop.close()
输出示例
waiter: 等待事件触发...
setter: 3 秒后触发事件
setter: 事件已触发
waiter: 事件已触发,继续执行
解释
asyncio.Event()
是一个简单的线程/协程同步工具。event.wait()
让协程挂起,直到事件状态变为“已设置”。event.set()
改变事件状态,所有等待它的协程会继续执行。loop.run_until_complete()
是手动控制事件循环的关键。