Python 协程全套核心模块

协程:单线程下并发,IO 等待时切换任务,开销远小于多线程,爬虫、接口压测、异步服务最常用。
 
核心内置模块:asyncio(Python3.4 + 自带,官方标准协程库)
 
配套常用拓展库:aiohttp、aiomysql、redis-py 异步版等

一、基础核心概念先理清

  1. async 关键字:定义协程函数,调用不会立刻执行,返回协程对象
  2. await:只能写在 async 函数内部,等待耗时 IO 操作(让出 CPU,切换其他任务)
  3. 事件循环 loop:协程调度器,负责管理、执行所有协程任务
  4. Task:将协程打包成任务,支持并发运行多个协程

二、asyncio 常用 API + 逐行可运行示例

示例 1:最简单协程入门(基础语法)

python
 
运行
 
 
import asyncio

# 1. 定义协程函数
async def hello():
    print("开始执行")
    # 异步休眠:await 让出CPU,不会阻塞整个线程
    await asyncio.sleep(2)
    print("执行完毕")

if __name__ == "__main__":
    # 方式1:Python3.7+ 推荐极简写法(自动创建、关闭事件循环)
    asyncio.run(hello())
 

示例 2:多个协程并发执行(核心用法)

同时跑多个任务,总耗时≈2s,串行需要 4s,体现协程并发优势
python
 
运行
 
 
import asyncio

async def task(name, delay):
    print(f"任务{name}启动,等待{delay}秒")
    await asyncio.sleep(delay)
    print(f"任务{name}完成")

async def main():
    # 创建多个协程任务
    t1 = asyncio.create_task(task("A", 2))
    t2 = asyncio.create_task(task("B", 2))
    # 等待所有任务执行结束
    await t1
    await t2

if __name__ == "__main__":
    asyncio.run(main())
 

示例 3:asyncio.gather () 批量并发(最常用)

一次性收集所有协程,等待全部完成,统一接收返回结果
python
 
运行
 
 
import asyncio

async def do_work(num):
    await asyncio.sleep(1)
    return f"结果{num}"

async def main():
    # 批量打包多个协程并发执行
    res_list = await asyncio.gather(
        do_work(1),
        do_work(2),
        do_work(3)
    )
    # 返回有序结果列表
    print(res_list)  # ['结果1', '结果2', '结果3']

asyncio.run(main())
 

示例 4:设置协程超时(避免卡死)

python
 
运行
 
 
import asyncio

async def long_task():
    await asyncio.sleep(5)
    return "完成"

async def main():
    try:
        # 最多等待3秒,超时直接抛出异常
        result = await asyncio.wait_for(long_task(), timeout=3)
        print(result)
    except asyncio.TimeoutError:
        print("任务超时终止")

asyncio.run(main())
 

示例 5:asyncio.wait 区分完成 / 未完成任务

python
 
运行
 
 
import asyncio

async def func(n):
    await asyncio.sleep(n)
    return n

async def main():
    tasks = [asyncio.create_task(func(1)), asyncio.create_task(func(3))]
    done, pending = await asyncio.wait(tasks, timeout=2)
    # done:已完成任务;pending:超时未结束任务
    print("已完成:", [t.result() for t in done])

asyncio.run(main())
 

三、协程常用第三方异步模块(测试 / 爬虫高频)

1. aiohttp 异步 HTTP 请求(接口自动化、异步爬虫首选)

对标同步 requests,异步发请求,上万接口并发效率极高
 
安装:pip install aiohttp
python
 
运行
 
 
import asyncio
import aiohttp

async def fetch(session, url):
    async with session.get(url) as resp:
        return await resp.json()

async def main():
    # 创建异步会话
    async with aiohttp.ClientSession() as session:
        # 并发请求多个接口
        urls = [
            "https://httpbin.org/get",
            "https://httpbin.org/headers"
        ]
        tasks = [fetch(session, url) for url in urls]
        results = await asyncio.gather(*tasks)
        print(results)

asyncio.run(main())
 

2. aiomysql:异步操作 MySQL 数据库

同步:pymysql | 异步:aiomysql,大量数据库查询场景提速明显
 
安装:pip install aiomysql

3. aioredis:异步 Redis 客户端

异步读写缓存,压测、高并发场景使用

四、面试高频考点

  1. 协程、线程、进程区别
    • 进程:资源隔离,开销最大,多核利用
    • 线程:操作系统调度,IO 密集型适用,有 GIL 锁限制 CPU 运算
    • 协程:用户态调度,单线程内切换,开销最小,只适合 IO 密集场景
  2. GIL 全局解释器锁:Python 同一时刻只有 1 个线程执行 CPU 代码,所以计算密集用多进程,IO 密集用多线程 / 协程
  3. await 只能跟可等待对象:协程、Task、Future
  4. 老版本 loop 写法(了解即可)
python
 
运行
 
 
loop = asyncio.get_event_loop()
loop.run_until_complete(hello())
loop.close()
 

五、易错点总结

  1. 普通函数不能 await,必须加 async
  2. time.sleep () 是同步阻塞!协程里一定要用 asyncio.sleep()
  3. 不能在循环里串行 await,要用 create_task/gather 实现并发
posted @ 2026-07-21 16:32  sjxm2017  阅读(0)  评论(0)    收藏  举报