Python异步编程asyncio详解
asyncio 是 Python 的异步编程框架,适合 IO 密集型任务,能大幅提升并发性能。
基本概念
python
import asyncio
async def hello():
print("Hello")
await asyncio.sleep(1) # 模拟IO操作
print("World")
# 运行协程
asyncio.run(hello())并发执行
python
import asyncio
import time
async def fetch_data(name, delay):
await asyncio.sleep(delay)
return f"{name}的数据"
async def main():
start = time.time()
# 串行执行:总耗时 = 1 + 2 + 3 = 6秒
# result1 = await fetch_data("A", 1)
# result2 = await fetch_data("B", 2)
# result3 = await fetch_data("C", 3)
# 并发执行:总耗时 = max(1, 2, 3) = 3秒
results = await asyncio.gather(
fetch_data("A", 1),
fetch_data("B", 2),
fetch_data("C", 3)
)
print(f"结果: {results}")
print(f"耗时: {time.time() - start:.1f}秒")
asyncio.run(main())异步 HTTP 请求
python
import asyncio
import aiohttp
async def fetch_page(session, url):
async with session.get(url) as response:
return await response.text()
async def crawl(urls):
async with aiohttp.ClientSession() as session:
tasks = [fetch_page(session, url) for url in urls]
return await asyncio.gather(*tasks)
urls = [f"https://httpbin.org/delay/{i}" for i in range(1, 6)]
results = asyncio.run(crawl(urls))信号量控制并发
python
import asyncio
async def limited_task(sem, task_id):
async with sem:
print(f"任务 {task_id} 开始")
await asyncio.sleep(1)
print(f"任务 {task_id} 完成")
return task_id
async def main():
sem = asyncio.Semaphore(3) # 最多同时3个
tasks = [limited_task(sem, i) for i in range(10)]
results = await asyncio.gather(*tasks)
print(f"完成: {results}")
asyncio.run(main())异步上下文管理器
python
import asyncio
class AsyncDatabase:
async def __aenter__(self):
print("连接数据库")
await asyncio.sleep(0.5)
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
print("关闭数据库连接")
await asyncio.sleep(0.5)
async def query(self, sql):
await asyncio.sleep(0.1)
return f"结果: {sql}"
async def main():
async with AsyncDatabase() as db:
result = await db.query("SELECT * FROM users")
print(result)
asyncio.run(main())TaskGroup(Python 3.11+)
python
import asyncio
async def main():
async with asyncio.TaskGroup() as tg:
task1 = tg.create_task(fetch_data("A", 1))
task2 = tg.create_task(fetch_data("B", 2))
# TaskGroup 结束后所有任务完成
print(task1.result(), task2.result())生产者-消费者
python
import asyncio
async def producer(queue, items):
for item in items:
await queue.put(item)
print(f"生产: {item}")
await asyncio.sleep(0.5)
await queue.put(None) # 结束信号
async def consumer(queue):
while True:
item = await queue.get()
if item is None:
break
print(f"消费: {item}")
await asyncio.sleep(1)
print("消费者结束")
async def main():
queue = asyncio.Queue(maxsize=5)
await asyncio.gather(
producer(queue, range(10)),
consumer(queue)
)
asyncio.run(main())总结
asyncio 适合网络请求、文件 IO 等等待型任务。async/await 语法让异步代码看起来像同步代码,asyncio.gather 实现并发,Semaphore 控制并发数。但要注意 asyncio 不适合 CPU 密集型任务(应使用 multiprocessing)。


评论 2