Python的asyncio库是标准库中用于编写异步IO代码的核心模块,它通过协程和事件循环的机制,让程序在等待IO操作(比如网络请求、文件读写)时不会阻塞整个线程,从而提升程序的执行效率,尤其适合处理大量并发的IO密集型任务。

asyncio核心概念
要掌握asyncio的使用,首先需要理解几个核心概念:
- 协程(Coroutine):协程是asyncio中的基本执行单元,本质是一种可以暂停和恢复的函数,使用
async def定义的函数就是协程函数,调用协程函数不会立即执行,而是返回一个协程对象。 - 事件循环(Event Loop):事件循环是asyncio的运行核心,负责调度和执行所有的协程任务,监听IO事件,当某个协程等待IO时,事件循环会暂停该协程,转去执行其他可运行的协程。
- await关键字:用于在协程内部等待另一个协程执行完成,await后面只能跟可等待对象(协程、任务、Future等),遇到await时,当前协程会暂停,让出执行权给事件循环。
基础使用示例
下面是一个最简单的asyncio使用示例,演示协程的定义和事件循环的启动:
import asyncio
# 定义协程函数
async def hello_async():
print("开始执行协程")
# 模拟IO等待,这里使用asyncio.sleep模拟非阻塞等待
await asyncio.sleep(1)
print("协程执行完成")
# 主函数
async def main():
# 调用协程函数,获取协程对象
coroutine = hello_async()
# 等待协程执行完成
await coroutine
if __name__ == "__main__":
# Python 3.7+可以直接使用asyncio.run启动事件循环
asyncio.run(main())
运行上述代码,会先打印"开始执行协程",等待1秒后打印"协程执行完成",整个过程不会阻塞主线程的其他逻辑(如果有其他协程的话)。
并发执行多个任务
asyncio的优势在于可以并发执行多个IO任务,不需要创建多个线程。我们可以使用asyncio.gather或者asyncio.create_task来并发运行多个协程:
使用asyncio.gather并发
import asyncio
import time
async def task(name, delay):
print(f"任务{name}开始执行,等待{delay}秒")
await asyncio.sleep(delay)
print(f"任务{name}执行完成")
return f"任务{name}的结果"
async def main():
start_time = time.time()
# 并发执行三个任务
results = await asyncio.gather(
task("A", 2),
task("B", 1),
task("C", 3)
)
end_time = time.time()
print(f"所有任务完成,结果:{results}")
print(f"总耗时:{end_time - start_time:.2f}秒")
if __name__ == "__main__":
asyncio.run(main())
上述代码中三个任务的等待时间分别是2秒、1秒、3秒,如果同步执行总耗时会是6秒,而并发执行总耗时约等于最长的3秒,因为三个任务是同时等待的。
使用create_task创建任务
asyncio.create_task可以将协程包装成任务,任务会被自动调度执行,不需要立即await:
import asyncio
async def task(name):
print(f"任务{name}开始")
await asyncio.sleep(1)
print(f"任务{name}结束")
return name
async def main():
# 创建两个任务,自动加入事件循环调度
task1 = asyncio.create_task(task("1"))
task2 = asyncio.create_task(task("2"))
# 等待两个任务完成
result1 = await task1
result2 = await task2
print(f"任务结果:{result1}, {result2}")
if __name__ == "__main__":
asyncio.run(main())
常见使用场景
asyncio最适合处理IO密集型的高并发场景,比如:
- 批量网络请求:比如同时请求多个API接口,不需要等待每个请求依次完成。
- 爬虫开发:同时爬取多个页面的内容,提升爬取效率。
- 异步文件读写:处理大量文件的读写操作,减少等待时间。
下面是一个简单的异步网络请求示例,使用aiohttp库(需要提前安装:pip install aiohttp)实现并发请求:
import asyncio
import aiohttp
async def fetch_url(session, url):
async with session.get(url) as response:
# 等待响应内容,非阻塞
content = await response.text()
print(f"请求{url}完成,响应长度:{len(content)}")
return content
async def main():
urls = [
"http://ipipp.com",
"http://ipipp.com/about",
"http://ipipp.com/contact"
]
async with aiohttp.ClientSession() as session:
# 并发请求所有url
await asyncio.gather(*[fetch_url(session, url) for url in urls])
if __name__ == "__main__":
asyncio.run(main())
注意事项
- 不要在协程中使用同步的阻塞操作(比如
time.sleep、同步的网络请求),这会阻塞整个事件循环,导致异步失去意义,同步阻塞操作要替换成对应的异步版本。 - asyncio是单线程的,不适合CPU密集型任务,CPU密集型任务还是需要使用多进程或者多线程处理。
- Python 3.7之前的版本启动事件循环需要使用
loop = asyncio.get_event_loop(); loop.run_until_complete(main())的方式,Python 3.7+推荐使用asyncio.run()。
异步编程的核心是利用IO等待的时间执行其他任务,而不是真正的并行执行,理解这一点才能更好地使用asyncio库。
asyncioPython异步编程协程事件循环async_await修改时间:2026-07-09 04:15:26