← 返回资讯
赵一鸣
产品评测编辑
已审核

Python 异步编程:从 asyncio 到生产级并发

title: "Python 异步编程:从 asyncio 到生产级并发"

Python 异步编程:从 asyncio 到生产级并发

title: "Python 异步编程:从 asyncio 到生产级并发"

date: "2026-07-10"

tags: ["Python", "异步", "asyncio", "并发"]


Python 异步编程:从 asyncio 到生产级并发

Python 的 asyncio 是处理 I/O 密集型任务的利器。理解其工作原理并正确使用,能显著提升应用性能。

基础概念

协程

PYTHON
import asyncio

async def fetch_data(url: str) -> dict:
    print(f"开始获取: {url}")
    await asyncio.sleep(1)  # 模拟 I/O 操作
    return {"url": url, "data": "response"}

async def main():
    result = await fetch_data("https://api.example.com")
    print(result)

asyncio.run(main())

并发执行

PYTHON
async def fetch_multiple():
    # 串行执行(慢)
    result1 = await fetch_data("https://api1.example.com")
    result2 = await fetch_data("https://api2.example.com")
    
    # 并发执行(快)
    result1, result2 = await asyncio.gather(
        fetch_data("https://api1.example.com"),
        fetch_data("https://api2.example.com")
    )
    
    return [result1, result2]

HTTP 客户端

PYTHON
import aiohttp
import asyncio

async def fetch_url(session: aiohttp.ClientSession, url: str) -> dict:
    async with session.get(url) as response:
        data = await response.json()
        return {"url": url, "status": response.status, "data": data}

async def fetch_all(urls: list[str]) -> list[dict]:
    async with aiohttp.ClientSession() as session:
        tasks = [fetch_url(session, url) for url in urls]
        return await asyncio.gather(*tasks)

# 使用
urls = [
    "https://api.example.com/users",
    "https://api.example.com/posts",
    "https://api.example.com/comments"
]

results = asyncio.run(fetch_all(urls))

异步 Web 服务

PYTHON
from fastapi import FastAPI
import asyncio

app = FastAPI()

async def get_user(user_id: str) -> dict:
    await asyncio.sleep(0.1)  # 模拟数据库查询
    return {"id": user_id, "name": "Alice"}

async def get_orders(user_id: str) -> list:
    await asyncio.sleep(0.2)  # 模拟数据库查询
    return [{"id": "1", "total": 100}]

@app.get("/api/dashboard/{user_id}")
async def dashboard(user_id: str):
    # 并发获取数据
    user, orders = await asyncio.gather(
        get_user(user_id),
        get_orders(user_id)
    )
    
    return {
        "user": user,
        "orders": orders,
        "order_count": len(orders)
    }

异步队列

PYTHON
import asyncio
from dataclasses import dataclass

@dataclass
class Task:
    id: str
    payload: dict

async def worker(queue: asyncio.Queue, worker_id: int):
    while True:
        task = await queue.get()
        try:
            print(f"Worker {worker_id} 处理任务: {task.id}")
            await process_task(task)
        finally:
            queue.task_done()

async def process_task(task: Task):
    await asyncio.sleep(0.5)  # 模拟处理
    print(f"任务完成: {task.id}")

async def main():
    queue: asyncio.Queue[Task] = asyncio.Queue()
    
    # 启动 5 个 worker
    workers = [
        asyncio.create_task(worker(queue, i))
        for i in range(5)
    ]
    
    # 添加任务
    for i in range(20):
        await queue.put(Task(id=f"task-{i}", payload={"index": i}))
    
    # 等待所有任务完成
    await queue.join()
    
    # 取消 worker
    for w in workers:
        w.cancel()

asyncio.run(main())

信号量控制并发

PYTHON
async def fetch_with_limit(urls: list[str], limit: int = 10):
    semaphore = asyncio.Semaphore(limit)
    
    async def fetch_limited(session: aiohttp.ClientSession, url: str):
        async with semaphore:
            return await fetch_url(session, url)
    
    async with aiohttp.ClientSession() as session:
        tasks = [fetch_limited(session, url) for url in urls]
        return await asyncio.gather(*tasks)

# 限制同时最多 10 个并发请求
results = asyncio.run(fetch_with_limit(urls, limit=10))

超时和取消

PYTHON
async def fetch_with_timeout(url: str, timeout: float = 5.0):
    try:
        async with asyncio.timeout(timeout):
            return await fetch_data(url)
    except TimeoutError:
        print(f"请求超时: {url}")
        return None

async def cancellable_task():
    task = asyncio.create_task(long_running_operation())
    
    # 3 秒后取消
    await asyncio.sleep(3)
    task.cancel()
    
    try:
        await task
    except asyncio.CancelledError:
        print("任务已取消")

异步上下文管理器

PYTHON
class AsyncDatabaseConnection:
    async def __aenter__(self):
        self.conn = await create_connection()
        return self.conn
    
    async def __aexit__(self, exc_type, exc_val, exc_tb):
        await self.conn.close()

# 使用
async def query_db():
    async with AsyncDatabaseConnection() as conn:
        result = await conn.execute("SELECT * FROM users")
        return result

异步迭代器

PYTHON
async def async_range(start: int, stop: int):
    for i in range(start, stop):
        await asyncio.sleep(0.1)
        yield i

async def main():
    async for i in async_range(0, 10):
        print(i)

生产级模式

重试机制

PYTHON
async def fetch_with_retry(
    session: aiohttp.ClientSession,
    url: str,
    max_retries: int = 3
) -> dict:
    for attempt in range(max_retries):
        try:
            async with session.get(url) as response:
                response.raise_for_status()
                return await response.json()
        except (aiohttp.ClientError, asyncio.TimeoutError) as e:
            if attempt == max_retries - 1:
                raise
            wait_time = 2 ** attempt  # 指数退避
            await asyncio.sleep(wait_time)

优雅关闭

PYTHON
import signal

async def graceful_shutdown(loop: asyncio.AbstractEventLoop):
    print("收到关闭信号,正在优雅关闭...")
    
    # 取消所有任务
    tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()]
    for task in tasks:
        task.cancel()
    
    await asyncio.gather(*tasks, return_exceptions=True)
    loop.stop()

async def main():
    loop = asyncio.get_running_loop()
    
    for sig in (signal.SIGTERM, signal.SIGINT):
        loop.add_signal_handler(
            sig,
            lambda: asyncio.create_task(graceful_shutdown(loop))
        )
    
    # 主逻辑
    await run_server()

Python 异步编程的关键是理解"协作式多任务":协程主动让出控制权,而不是被强制中断。正确使用 async/await,能让 I/O 密集型应用的性能提升数倍。

513
10267 阅读
5 评论
分享
链接已复制
编辑说明

本文由 MakeSense 编辑团队撰写并审核。文中引用的数据和观点均经过交叉验证,如有疏漏欢迎在评论区指正。最后更新:2026年07月11日 08:57

赵一鸣

产品评测编辑

前产品经理,现专注 AI 工具评测。实测过 30+ 款 AI 产品,擅长横向对比和用户体验分析。

读者评论 5

前端工程师 2周前
代码示例很清晰,直接用到项目里了。
回复 点赞 (6)
技术小白 3天前
作为非技术人员也看懂了,感谢作者的通俗讲解。
回复 点赞 (3)
Dev小王 6天前
终于有人把这个说清楚了,收藏了。
回复 点赞 (8)
A
AI研究员 1周前
观点有道理,不过我觉得还需要考虑算力成本的问题。
回复 点赞 (11)
M
创业者Mark 1周前
正在做相关方向,这篇文章给了我不少启发。
回复 点赞 (7)