Skip to content

Python 协程

1. 协程的概念

协程是一种 用户态的轻量级线程,它与线程类似可以执行任务,但更轻量、不依赖操作系统线程。Python 协程通过 async/await 关键字实现。

特点:

  1. 非阻塞:协程可以在等待 I/O 时暂停自己,让出执行权,其他协程可以继续执行。
  2. 单线程内实现高并发:不像多线程多进程,需要线程切换开销,协程切换开销极小。
  3. 协作式调度:协程主动“让出”执行权,而不是操作系统强制切换。

通俗理解:

  • 线程是“抢资源做事”,操作系统说谁先运行就先运行。
  • 协程是“按顺序做事”,任务自己说什么时候暂停,什么时候继续。

2. Python 协程基础

2.1 定义协程

Python 3.5+ 使用 async def 定义协程函数:

python
import asyncio

async def say_hello():
    print("Hello")
    await asyncio.sleep(1)  # 模拟耗时操作
    print("World")

这里的 await 表示挂起协程,等待某个异步操作完成。

2.2 调用协程

协程函数本身不会立即执行,需要通过事件循环运行:

python
asyncio.run(say_hello())

事件循环(Event Loop)是协程运行的核心,它负责调度协程的执行和挂起。


3. 协程 vs 线程 vs 同步 I/O

特性同步线程协程
并发方式串行并行/并发并发
I/O阻塞会阻塞不阻塞不阻塞
开销很小
切换方式N/A系统调度协作调度

例子对比(异步下载多个网页):

  • 同步:
python
def download(url):
    # 阻塞 I/O
    pass

for url in urls:
    download(url)
  • 协程:
python
async def download(url):
    await aiohttp.get(url)  # 非阻塞

协程可以在等待网络请求时执行其他任务,提高效率。


4. asyncio 库核心概念

  1. 协程函数:用 async def 定义。
  2. Task:任务对象,包装协程,交给事件循环执行。
  3. 事件循环:调度所有协程任务。
  4. Future:表示异步操作的最终结果。

示例:

python
import asyncio

async def task(name, delay):
    print(f"{name} 开始")
    await asyncio.sleep(delay)
    print(f"{name} 结束")
    return f"{name} result"

async def main():
    t1 = asyncio.create_task(task("A", 2))
    t2 = asyncio.create_task(task("B", 1))
    
    results = await asyncio.gather(t1, t2)
    print(results)

asyncio.run(main())

输出顺序

A 开始
B 开始
B 结束
A 结束
['A result', 'B result']

解释:

  • 协程 A 和 B 并发执行。
  • B 耗时更短,所以先结束。

5. 使用协程的场景

  1. 高并发 I/O 密集型任务:Web 服务、爬虫、网络请求。
  2. 异步操作:数据库查询、文件读写、网络通信。
  3. GUI、游戏循环:避免阻塞界面。

注意

  • 协程不适合 CPU 密集型任务,计算密集型任务仍需多线程或多进程。

6. 小结

  • 协程 = 用户态轻量线程,靠 await 挂起和恢复。
  • Python 协程基于 asyncio,核心是事件循环。
  • 协程非常适合 高并发 I/O 场景
  • 学好协程,可以写出既高效又轻量的网络程序。

随便写写的,喜欢就好。 使用VitePress构建