返回文章列表

文章

Python的asyncio

asyncio的基本使用

目录
  1. 下面从“基本用法”和“典型场景”两方面来介绍 Python asyncio。
  2. 一、基本用法
  3. 1.1 启动事件循环
  4. 1.2 任务(Task)和并发执行
  5. 1.3 控制并发量:信号量(Semaphore)
  6. 1.4 超时管理:wait_for
  7. 二、典型使用场景
  8. 三、小结

下面从“基本用法”和“典型场景”两方面来介绍 Python asyncio#

一、基本用法#

1.1 启动事件循环#

import asyncio

async def main():
    print("Hello")
    await asyncio.sleep(1)
    print("World")

# Python 3.7+ 推荐写法
asyncio.run(main())

  • async def 定义一个 协程函数(coroutine function),调用它将返回一个协程对象(coroutine)。
  • await 用于在协程内部挂起当前任务,等待另一个协程或 Future 完成。
  • asyncio.run(...) 会创建并管理一个事件循环,将指定的顶层协程运行到完成,然后关闭循环。

1.2 任务(Task)和并发执行#

import asyncio

async def worker(name, delay):
    await asyncio.sleep(delay)
    print(f"{name} 完成,耗时 {delay}s")

async def main():
    # 三个任务并发启动
    t1 = asyncio.create_task(worker("任务A", 2))
    t2 = asyncio.create_task(worker("任务B", 1))
    t3 = asyncio.create_task(worker("任务C", 3))

    # 等待所有任务完成
    await asyncio.gather(t1, t2, t3)

asyncio.run(main())

  • asyncio.create_task(coro):将协程包装成 Task,交给事件循环调度。
  • asyncio.gather(...):并发地等待一组协程或 Task,返回它们的结果列表。

1.3 控制并发量:信号量(Semaphore)#

import asyncio
from random import random

sem = asyncio.Semaphore(3)  # 同时最多 3 个并发

async def bound_worker(i):
    async with sem:
        delay = random() * 2
        await asyncio.sleep(delay)
        print(f"工作 {i} 完成({delay:.2f}s)")

async def main():
    tasks = [asyncio.create_task(bound_worker(i)) for i in range(10)]
    await asyncio.gather(*tasks)

asyncio.run(main())

  • asyncio.Semaphore(n) 用来限制并发量,防止同时启动过多操作(如 HTTP 请求)而导致资源枯竭。

1.4 超时管理:wait_for#

import asyncio

async def long_op():
    await asyncio.sleep(5)
    return "结果"

async def main():
    try:
        # 最多等 2 秒,超时则抛 TimeoutError
        res = await asyncio.wait_for(long_op(), timeout=2)
        print(res)
    except asyncio.TimeoutError:
        print("操作超时")

asyncio.run(main())


二、典型使用场景#

  1. 高并发网络 IO
    • HTTP 客户端/爬虫:同时对上百甚至上千个目标发起请求,用 aiohttphttpx.AsyncClient
    • WebSocket 客户端/服务器:实时双向通信,用 websocketsaiohttp 的 WebSocket 支持。
  2. 异步 Web 服务
    • 框架如 FastAPIaiohttp.webSanic 等,基于 asyncio,可以在单个进程中高效地并发处理大量 HTTP 请求。
  3. 数据库异步驱动
    • 异步 ORM/驱动:databases + SQLAlchemyasyncpg(PostgreSQL)、aiomysql(MySQL),有助于在使用协程的服务中避免阻塞。
  4. 消息队列与后台任务
    • 与 RabbitMQ、Kafka、Redis Stream 等异步交互,使用 aio-pikaaiokafkaaredis 等库,实现高吞吐的消息消费。
  5. 异步定时与调度
    • 周期性任务:在事件循环内用 asyncio.sleepaiocron 定时执行定时器逻辑。
  6. 并行化文件 IO
    • 虽然 Python 标准库文件 IO 是同步的,但通过 aiofiles 可实现异步读写,适用于大量磁盘操作场景。

三、小结#

  • 优点:在单线程下用协作式多任务(协程)来高效并发处理大量 IO 操作,节省线程/进程开销。
  • 缺点:CPU 密集型任务依旧需要使用多线程或多进程;需要第三方库支持异步接口。
  • 选型建议
    • 如果你项目主要瓶颈在网络/IO,且有高并发需求,asyncio + 异步库 是首选。
    • 如果只是简单脚本或 CPU 密集型运算,则普通同步或多进程/多线程更易实现。 希望这些示例和场景能帮助你上手并正确选用 asyncio